美文网首页
golang之mapstructure简单使用

golang之mapstructure简单使用

作者: 夜空最亮的9星 | 来源:发表于2023-12-27 16:47 被阅读0次

导包

     go get github.com/goinggo/mapstructure

字段映射

import (
    "fmt"
    "github.com/mitchellh/mapstructure"
    "testing"
)
## 源结构体
type Person struct {
    Name    string `json:"name"`
    Address string `json:"address"`
    Age     int    `json:"age"`
}

## 目标结构体
type Student struct {
    UserName    string `json:"userName" mapstructure:"name"`
    UserAddress string `json:"userAddress" mapstructure:"address"`
    UserAge     int    `json:"userAge" mapstructure:"age"`
}

func Test_mapstruct001(t *testing.T) {
    p1 := Person{Name: "韩立",
        Address: "北京",
        Age:     29,
    }
    var s2 Student
    mapstructure.Decode(p1, &s2)
    fmt.Printf("%+v\n", p1) // {Name:韩立 Address:北京 Age:29}
    fmt.Printf("%+v\n", s2) // {UserName:韩立 UserAddress:北京 UserAge:29}
}

json 转 struct

json 转换成 struct 只需要使用 json.unmashal 即可

map 转换成 struct


type Blog struct {
    BlogId  string `mapstructure:"blogId"`
    Title   string `mapstructrue:"title"`
    Content string `mapstructure:"content"`
    Uid     string `mapstructure:"uid"`
    State   string `mapstructure:"state"`
}

type Event struct {
    Type     string              `json:"type"`
    Database string              `json:"database"`
    Table    string              `json:"table"`
    Data     []map[string]string `json:"data"`
}

func TestMapStructure(t *testing.T) {
    e := Event{}
    msg := []byte(`{
    "type": "UPDATE",
    "database": "blog",
    "table": "blog",
    "data": [
        {
            "blogId": "100001",
            "title": "title",
            "content": "this is a blog",
            "uid": "1000012",
            "state": "1"
        }
    ]
}`)
    if err := json.Unmarshal(msg, &e); err != nil {
        panic(err)
    }
    if e.Table == "blog" {
        var blogs []Blog
        if err := mapstructure.Decode(e.Data, &blogs); err != nil {
            panic(err)
        }
        fmt.Println(blogs)
    }

}

在线json转struct的工具:https://mholt.github.io/json-to-go/

mapstructure_examples_test.go

package mapstructure

import (
    "fmt"
)

func ExampleDecode() {
    type Person struct {
        Name   string
        Age    int
        Emails []string
        Extra  map[string]string
    }

    // This input can come from anywhere, but typically comes from
    // something like decoding JSON where we're not quite sure of the
    // struct initially.
    input := map[string]interface{}{
        "name":   "Mitchell",
        "age":    91,
        "emails": []string{"one", "two", "three"},
        "extra": map[string]string{
            "twitter": "mitchellh",
        },
    }

    var result Person
    err := Decode(input, &result)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v", result)
    // Output:
    // mapstructure.Person{Name:"Mitchell", Age:91, Emails:[]string{"one", "two", "three"}, Extra:map[string]string{"twitter":"mitchellh"}}
}

func ExampleDecode_errors() {
    type Person struct {
        Name   string
        Age    int
        Emails []string
        Extra  map[string]string
    }

    // This input can come from anywhere, but typically comes from
    // something like decoding JSON where we're not quite sure of the
    // struct initially.
    input := map[string]interface{}{
        "name":   123,
        "age":    "bad value",
        "emails": []int{1, 2, 3},
    }

    var result Person
    err := Decode(input, &result)
    if err == nil {
        panic("should have an error")
    }

    fmt.Println(err.Error())
    // Output:
    // 5 error(s) decoding:
    //
    // * 'Age' expected type 'int', got unconvertible type 'string', value: 'bad value'
    // * 'Emails[0]' expected type 'string', got unconvertible type 'int', value: '1'
    // * 'Emails[1]' expected type 'string', got unconvertible type 'int', value: '2'
    // * 'Emails[2]' expected type 'string', got unconvertible type 'int', value: '3'
    // * 'Name' expected type 'string', got unconvertible type 'int', value: '123'
}

func ExampleDecode_metadata() {
    type Person struct {
        Name string
        Age  int
    }

    // This input can come from anywhere, but typically comes from
    // something like decoding JSON where we're not quite sure of the
    // struct initially.
    input := map[string]interface{}{
        "name":  "Mitchell",
        "age":   91,
        "email": "foo@bar.com",
    }

    // For metadata, we make a more advanced DecoderConfig so we can
    // more finely configure the decoder that is used. In this case, we
    // just tell the decoder we want to track metadata.
    var md Metadata
    var result Person
    config := &DecoderConfig{
        Metadata: &md,
        Result:   &result,
    }

    decoder, err := NewDecoder(config)
    if err != nil {
        panic(err)
    }

    if err := decoder.Decode(input); err != nil {
        panic(err)
    }

    fmt.Printf("Unused keys: %#v", md.Unused)
    // Output:
    // Unused keys: []string{"email"}
}

func ExampleDecode_weaklyTypedInput() {
    type Person struct {
        Name   string
        Age    int
        Emails []string
    }

    // This input can come from anywhere, but typically comes from
    // something like decoding JSON, generated by a weakly typed language
    // such as PHP.
    input := map[string]interface{}{
        "name":   123,                      // number => string
        "age":    "42",                     // string => number
        "emails": map[string]interface{}{}, // empty map => empty array
    }

    var result Person
    config := &DecoderConfig{
        WeaklyTypedInput: true,
        Result:           &result,
    }

    decoder, err := NewDecoder(config)
    if err != nil {
        panic(err)
    }

    err = decoder.Decode(input)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v", result)
    // Output: mapstructure.Person{Name:"123", Age:42, Emails:[]string{}}
}

func ExampleDecode_tags() {
    // Note that the mapstructure tags defined in the struct type
    // can indicate which fields the values are mapped to.
    type Person struct {
        Name string `mapstructure:"person_name"`
        Age  int    `mapstructure:"person_age"`
    }

    input := map[string]interface{}{
        "person_name": "Mitchell",
        "person_age":  91,
    }

    var result Person
    err := Decode(input, &result)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v", result)
    // Output:
    // mapstructure.Person{Name:"Mitchell", Age:91}
}

func ExampleDecode_embeddedStruct() {
    // Squashing multiple embedded structs is allowed using the squash tag.
    // This is demonstrated by creating a composite struct of multiple types
    // and decoding into it. In this case, a person can carry with it both
    // a Family and a Location, as well as their own FirstName.
    type Family struct {
        LastName string
    }
    type Location struct {
        City string
    }
    type Person struct {
        Family    `mapstructure:",squash"`
        Location  `mapstructure:",squash"`
        FirstName string
    }

    input := map[string]interface{}{
        "FirstName": "Mitchell",
        "LastName":  "Hashimoto",
        "City":      "San Francisco",
    }

    var result Person
    err := Decode(input, &result)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%s %s, %s", result.FirstName, result.LastName, result.City)
    // Output:
    // Mitchell Hashimoto, San Francisco
}

func ExampleDecode_remainingData() {
    // Note that the mapstructure tags defined in the struct type
    // can indicate which fields the values are mapped to.
    type Person struct {
        Name  string
        Age   int
        Other map[string]interface{} `mapstructure:",remain"`
    }

    input := map[string]interface{}{
        "name":  "Mitchell",
        "age":   91,
        "email": "mitchell@example.com",
    }

    var result Person
    err := Decode(input, &result)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v", result)
    // Output:
    // mapstructure.Person{Name:"Mitchell", Age:91, Other:map[string]interface {}{"email":"mitchell@example.com"}}
}

func ExampleDecode_omitempty() {
    // Add omitempty annotation to avoid map keys for empty values
    type Family struct {
        LastName string
    }
    type Location struct {
        City string
    }
    type Person struct {
        *Family   `mapstructure:",omitempty"`
        *Location `mapstructure:",omitempty"`
        Age       int
        FirstName string
    }

    result := &map[string]interface{}{}
    input := Person{FirstName: "Somebody"}
    err := Decode(input, &result)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v", result)
    // Output:
    // &map[Age:0 FirstName:Somebody]
}

相关文章

网友评论

      本文标题:golang之mapstructure简单使用

      本文链接:https://www.haomeiwen.com/subject/bhorndtx.html