开启成长之旅!这是我参与「日新计划 12 月更文挑战」的第22天,点击查看活动详情
耐心和持久胜过激烈和疯狂。
哈喽大家好,我是陈明勇,今日分享的内容是 Go 结构体与 JSON 之间的转化。假如本文对你有帮助,无妨点个赞,假如你是 Go 言语初学者,无妨点个关注,一起成长一起前进,假如本文有错误的当地,欢迎指出!
前语
在日常开发中,咱们往往会将 JSON
解析成对应的结构体,反之也会将结构体转成 JSON
。接下来本文会经过 JSON
包的两个函数,来介绍 JSON
与结构体之间的转化。
结构体转 JSON
Marshal(v any) ([]byte, error)
:将 v
转成 JSON
数据,以 []byte
的形式返回。
import (
"encoding/json"
"fmt"
)
type User struct {
Name string
Age int
Height float64
Weight *float64
Child bool
marriageStatus string
}
func main() {
weight := 120.5
user := User{
Name: "gopher",
Age: 18,
Height: 180.5,
Weight: &weight,
Child: false,
marriageStatus: "未婚",
}
jsonBytes, err := json.Marshal(user)
if err != nil {
fmt.Println("error: ", err)
return
}
fmt.Println(string(jsonBytes)) // {"Name":"gopher","Age":18,"Height":180.5,"Weight":120.5,"Child":false}
}
履行成果:
{"Name":"gopher","Age":18,"Height":180.5,"Weight":120.5,"Child":false}
依据成果可知:
- 不行导出字段(字段名以小写字母最初),是不能被转成
JSON
的key
的,这也符合Go
的语法规定,以小写字母最初的变量或结构体字段等,不能在包外被拜访。 - 转化后的字段名,与结构体字段的名字相同。
- 假如字段是指针类型,转化后的值为指针指向的字段值。
假如咱们想要指定字段转化之后的命名,或许将一个可导出的字段进行疏忽,可以经过给结构体字段打上 JSON
标签的方法完成。
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Height float64 `json:"height"`
Weight *float64 `json:"weight"`
Child bool `json:"child"`
MarriageStatus string `json:"-"`
}
func main() {
weight := 120.5
user := User{
Name: "gopher",
Age: 18,
Height: 180.5,
Weight: &weight,
Child: false,
MarriageStatus: "未婚",
}
jsonBytes, err := json.Marshal(user)
if err != nil {
fmt.Println("error: ", err)
return
}
fmt.Println(string(jsonBytes)) // {"name":"gopher","age":18,"height":180.5,"weight":120.5,"child":false}
}
经过给结构体字段定打上 JSON
标签,可指定转成 JSON
后的字段名,假如 JSON
标签的值为 -
,则在转化 JSON
时疏忽此字段。
JSON 解析结构体
Unmarshal(data []byte, v any) error
:将 JSON
解析成指定的结构体。
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Height float64 `json:"height"`
Child bool `json:"-"`
marriageStatus string
}
func main() {
userStr := `
{
"name": "gopher",
"age": 18,
"height": 180.5,
"child": true,
"marriageStatus": "未婚"
}
`
user := &User{}
err := json.Unmarshal([]byte(userStr), &user)
if err != nil {
fmt.Println("error: ", err)
return
}
fmt.Printf("%#v", user) // &main.User{Name:"gopher", Age:18, Height:180.5, Child:false, marriageStatus:""}
}
履行成果:&main.User{Name:"gopher", Age:18, Height:180.5, Child:false, marriageStatus:""}
依据成果可知:
- 运用
Unmarshal
函数时,咱们需求传入结构体的指针类型,不然结构体字段的值将不会被改变,由于底层是经过指针去修改结构体字段的值。 -
JSON
解析时,JSON
的key
与结构体字段的匹配规则是:- 优先查找
JSON
标签值和key
相同的,找到则将value
赋值给对应字段。 - 假如没有
JSON
标签值与key
相匹配,则依据字段名进行匹配。
- 优先查找
- 可以发现,假如结构体字段是非导出字段或
JSON
标签的值为-
,将不会被匹配到。
小结
本文介绍了 Go
言语里,JSON
与结构体之间的转化。在结构体转 JSON
时,咱们可以经过给字段打标签,指定转化后的 key
命名,需求留意的是,假如结构体的字段为非导出字段或字段的 JSON
标签值为 -
,在转化 JSON
时,将会被疏忽。反之 JSON
解析结构体时也是相同的。