在go中struct(结构体)json对象很相似,那么就有方法将其互转

struct转json字符串

package main

import (
    "encoding/json"
    "fmt"
)

func main() {

    type Addr struct {
        Area        string `json:"area"`
        Street      string `json:"street"`
        HouseNumber int    `json:"houseNumber"`
    }

    type Person struct {
        Username string   `json:"username"`
        Age      int      `json:"age"`
        Friend   []string `json:"friend"`
        Addr     Addr     `json:"addr"`
    }

    person := Person{
        Username: "小红",
        Age:      20,
        Friend:   []string{"小明", "小花"},
        Addr: Addr{
            Area:        "武汉市",
            Street:      "光谷大道",
            HouseNumber: 1,
        },
    }

    // 转换struce后返回的是[]byte
    obj, err := json.Marshal(person)

    // 错误处理
    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }

    // 将[]byte转换为string后输出
    fmt.Printf("%v\n", string(obj))
}

打印的结果为

{
    "username": "小红",
    "age": 20,
    "friend": [
        "小明",
        "小花"
    ],
    "addr": {
        "area": "武汉市",
        "street": "光谷大道",
        "houseNumber": 1
    }
}

其中,slice(切片)转化结果为array,内层struct转化为内层json对象

需要注意以下几点:

  1. 内层struct必须优先定义,否则会出现undefined问题
  2. struct内的key(键)必须要首字母大写,否则这个key-value会被直接丢弃
  3. 转换后的键名,可以通过字段的tag来指定,如json:"username"。可以解决转换后大小写问题

json字符串转化为struct

已知json的key

package main

import (
    "encoding/json"
    "fmt"
)

func main() {

    type Addr struct {
        Area        string
        Street      string
        HouseNumber int
    }

    type Person struct {
        Username string
        Age      int
        Friend   []string
        Addr     Addr
    }

    person := Person{}

    obj := "{\"username\":\"小红\",\"age\":20,\"friend\":[\"小明\",\"小花\"],\"addr\":{\"area\":\"武汉市\",\"street\":\"光谷大道\",\"houseNumber\":1}}"

    // 将string转为slice以供转化,并做错误处理
    err := json.Unmarshal([]byte(obj), &person)

    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }

    fmt.Printf("%v\n", person)
    // {小红 20 [小明 小花] {武汉市 光谷大道 1}}
}

未知json的key

interface{}可以用来存储任意数据类型的对象,这种数据结构正好用于存储解析的未知结构的json数据的结果

package main

import (
    "encoding/json"
    "fmt"
)

func main() {

    var person map[string]interface{}

    obj := "{\"username\":\"小红\",\"age\":20,\"friend\":[\"小明\",\"小花\"],\"addr\":{\"area\":\"武汉市\",\"street\":\"光谷大道\",\"houseNumber\":1}}"

    err := json.Unmarshal([]byte(obj), &person)

    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }

    fmt.Printf("%v\n", person)
    // map[addr:map[area:武汉市 houseNumber:1 street:光谷大道] age:20 friend:[小明 小花] username:小红]
    fmt.Printf("%v\n", person["addr"])
    // map[area:武汉市 houseNumber:1 street:光谷大道]
    fmt.Printf("%v\n", person["username"])
    // 小红

    // 内层json结构,需要使用.(map[string]interface{})进行类型转换
    area := person["addr"].(map[string]interface{})["area"]
    
    fmt.Printf("%v\n", area)
    // 武汉市
}

参考文档

golang-web: struct结构体转成JSON
Go中结构体的使用
go语言基础 结构体嵌套
golang解析json
Go 解析JSON
golang中struct转json后键名首字母大小写问题解决

Last modification:October 28, 2019
If you think my article is useful to you, please feel free to appreciate