admin管理员组文章数量:1130349
简介
mapstructure用于将通用的map[string]interface{}解码到对应的 Go 结构体中,或者执行相反的操作。很多时候,解析来自多种源头的数据流时,我们一般事先并不知道他们对应的具体类型。只有读取到一些字段之后才能做出判断。这时,我们可以先使用标准的encoding/json库将数据解码为map[string]interface{}类型,然后根据标识字段利用mapstructure库转为相应的 Go 结构体以便使用。
快速使用
本文代码采用 Go Modules。
首先创建目录并初始化:
$ mkdir mapstructure && cd mapstructure
$ go mod init github/darjun/go-daily-lib/mapstructure
下载mapstructure库:
$ go get github/mitchellh/mapstructure
使用:
package main
import (
"encoding/json"
"fmt"
"log"
"github/mitchellh/mapstructure"
)
type Person struct {
Name string
Age int
Job string
}
type Cat struct {
Name string
Age int
Breed string
}
func main() {
datas := []string{`
{
"type": "person",
"name":"dj",
"age":18,
"job": "programmer"
}
`,
`
{
"type": "cat",
"name": "kitty",
"age": 1,
"breed": "Ragdoll"
}
`,
}
for _, data := range datas {
var m map[string]interface{}
err := json.Unmarshal([]byte(data), &m)
if err != nil {
log.Fatal(err)
}
switch m["type"].(string) {
case "person":
var p Person
mapstructure.Decode(m, &p)
fmt.Println("person", p)
case "cat":
var cat Cat
mapstructure.Decode(m, &cat)
fmt.Println("cat", cat)
}
}
}
运行结果:
$ go run main.go
person {dj 18 programmer}
cat {kitty 1 Ragdoll}
我们定义了两个结构体Person和Cat,他们的字段有些许不同。现在,我们约定通信的 JSON 串中有一个type字段。当type的值为person时,该 JSON 串表示的是Person类型的数据。当type的值为cat时,该 JSON 串表示的是Cat类型的数据。
上面代码中,我们先用json.Unmarshal将字节流解码为map[string]interface{}类型。然后读取里面的type字段。根据type字段的值,再使用mapstructure.Decode将该 JSON 串分别解码为Person和Cat类型的值,并输出。
实际上,Google Protobuf 通常也使用这种方式。在协议中添加消息 ID 或全限定消息名。接收方收到数据后,先读取协议 ID 或全限定消息名。然后调用 Protobuf 的解码方法将其解码为对应的Message结构。从这个角度来看,mapstructure也可以用于网络消息解码,如果你不考虑性能的话
简介
mapstructure用于将通用的map[string]interface{}解码到对应的 Go 结构体中,或者执行相反的操作。很多时候,解析来自多种源头的数据流时,我们一般事先并不知道他们对应的具体类型。只有读取到一些字段之后才能做出判断。这时,我们可以先使用标准的encoding/json库将数据解码为map[string]interface{}类型,然后根据标识字段利用mapstructure库转为相应的 Go 结构体以便使用。
快速使用
本文代码采用 Go Modules。
首先创建目录并初始化:
$ mkdir mapstructure && cd mapstructure
$ go mod init github/darjun/go-daily-lib/mapstructure
下载mapstructure库:
$ go get github/mitchellh/mapstructure
使用:
package main
import (
"encoding/json"
"fmt"
"log"
"github/mitchellh/mapstructure"
)
type Person struct {
Name string
Age int
Job string
}
type Cat struct {
Name string
Age int
Breed string
}
func main() {
datas := []string{`
{
"type": "person",
"name":"dj",
"age":18,
"job": "programmer"
}
`,
`
{
"type": "cat",
"name": "kitty",
"age": 1,
"breed": "Ragdoll"
}
`,
}
for _, data := range datas {
var m map[string]interface{}
err := json.Unmarshal([]byte(data), &m)
if err != nil {
log.Fatal(err)
}
switch m["type"].(string) {
case "person":
var p Person
mapstructure.Decode(m, &p)
fmt.Println("person", p)
case "cat":
var cat Cat
mapstructure.Decode(m, &cat)
fmt.Println("cat", cat)
}
}
}
运行结果:
$ go run main.go
person {dj 18 programmer}
cat {kitty 1 Ragdoll}
我们定义了两个结构体Person和Cat,他们的字段有些许不同。现在,我们约定通信的 JSON 串中有一个type字段。当type的值为person时,该 JSON 串表示的是Person类型的数据。当type的值为cat时,该 JSON 串表示的是Cat类型的数据。
上面代码中,我们先用json.Unmarshal将字节流解码为map[string]interface{}类型。然后读取里面的type字段。根据type字段的值,再使用mapstructure.Decode将该 JSON 串分别解码为Person和Cat类型的值,并输出。
实际上,Google Protobuf 通常也使用这种方式。在协议中添加消息 ID 或全限定消息名。接收方收到数据后,先读取协议 ID 或全限定消息名。然后调用 Protobuf 的解码方法将其解码为对应的Message结构。从这个角度来看,mapstructure也可以用于网络消息解码,如果你不考虑性能的话
本文标签: Mapstructure
版权声明:本文标题:Go 每日一库之 mapstructure 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/jiaocheng/1755047050a2759762.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论