[TOC] > [github](https://github.com/mitchellh/mapstructure) ## 安装 `go get https://github.com/mitchellh/mapstructure` ## 使用 ### Decode 一: ``` type Person struct { Name string Age int Emails []string Extra map[string]string } input := map[string]interface{}{ "name": "Mitchell", "age": 91, "emails": []string{"one", "two", "three"}, "extra": map[string]string{ "twitter": "mitchellh", }, } var result Person err := mapstructure.Decode(input, &result) if err != nil { panic(err) } fmt.Printf("%#v", result) //main.Person{Name:"Mitchell", Age:91, Emails:[]string{"one", "two", "three"}, Extra:map[string]string{"twitter":"mitchellh"}} ``` 二: ``` type Family struct { LastName string } type Location struct { City string } type Person struct { Family Family `mapstructure:",squash"` Location `mapstructure:",squash"` FirstName string } input := map[string]interface{}{ "FirstName": "Mitchell", "LastName": "Hashimoto", "City": "San Francisco", } var result Person err := mapstructure.Decode(input, &result) if err != nil { panic(err) } fmt.Printf("%s,%s,%s", result.FirstName, result.Family.LastName, result.City) //Mitchell,Hashimoto,San Francisco ``` ### 查看多余的 key ``` 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 mapstructure.Metadata var result Person config := &mapstructure.DecoderConfig{ Metadata: &md, Result: &result, } decoder, err := mapstructure.NewDecoder(config) if err != nil { panic(err) } if err := decoder.Decode(input); err != nil { panic(err) } fmt.Printf(" keys: %#v\n", md.Keys) // keys: []string{"Name", "Age" fmt.Printf("Unused keys: %#v\n", md.Unused) //Unused keys: []string{"email"} ``` ### 指定 map的key 对应 struct ``` 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 := mapstructure.Decode(input, &result) if err != nil { panic(err) } fmt.Printf("%#v", result) //main.Person{Name:"Mitchell", Age:91} ``` ### 值类型与 struct 不同时,进行转换 ``` type Person struct { Name string Age int Emails []string } // 像php 一样进行转换 ,如 bools to string (true = "1", false = "0") input := map[string]interface{}{ "name": 123, // number => string "age": "42", // string => number "emails": map[string]interface{}{}, // empty map => empty array } var result Person config := &mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: &result, } decoder, err := mapstructure.NewDecoder(config) if err != nil { panic(err) } err = decoder.Decode(input) if err != nil { panic(err) } fmt.Printf("%#v", result) //main.Person{Name:"123", Age:42, Emails:[]string{}} ```