mapstructure map 转 struct
最后更新于:2022-04-02 02:39:23
[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{}}
```
';