开启成长之旅!这是我参与「日新计划 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}

依据成果可知:

  • 不行导出字段(字段名以小写字母最初),是不能被转成 JSONkey 的,这也符合 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 解析时,JSONkey 与结构体字段的匹配规则是:

    • 优先查找 JSON 标签值和 key 相同的,找到则将 value 赋值给对应字段。
    • 假如没有 JSON 标签值与 key 相匹配,则依据字段名进行匹配。
  • 可以发现,假如结构体字段是非导出字段或 JSON 标签的值为 -,将不会被匹配到。

小结

本文介绍了 Go 言语里,JSON 与结构体之间的转化。在结构体转 JSON 时,咱们可以经过给字段打标签,指定转化后的 key 命名,需求留意的是,假如结构体的字段为非导出字段或字段的 JSON 标签值为 -,在转化 JSON 时,将会被疏忽。反之 JSON 解析结构体时也是相同的。