目录
  • 序列化
    • 1. 结构体序列化
    • 2. 字典序列化
    • 3. 切片序列化
  • 反序列化
    • 1. 明确知道 JSON 格式
    • 2. 无法确定 JSON 格式

Go 语言中的 encoding/json 库提供了复杂的将 Go 中各种类型与JSON格式之间转换的功能, 我们主要使用以下几个功能:

  • 将一个切片、结构体或字典序列化成 JSON 格式的字符串【字节流】。
  • 将一个 JSON 格式的字符串【字节流】反序列化成一个切片、结构体或字典。

序列化

Marshal
func Marshal(vinterface{}) ([]byte, error)

1. 结构体序列化

比如使用以下的结构体表示一部电影:

typeMovie struct {    Title  string    Year   int  `json:"released"`    Color  bool `json:"color,omitempty"`    Actors []string}
json:"released"json:"color,omitempty
json:"released"json:"color,omitempty"false

没有 field tags 时进行序列化的一些规则:

  • 如果结构体成员的名字不是以大写字母开头,则不对它进行序列化。
  • 如果结构体成员的名字是以大写字母开头,则序列化后的名字就是成员名。

进行序列化的代码如下:

movie := Movie{        Title:  "Casablanca",        Year:   1942,        Color:  false,        Actors: []string{"Humphrey Bogart", "Ingrid Bergman"},    }        data, err := json.Marshal(movie)    if err != nil {        log.Fatalf("JSON marshaling failed: %s", err)    }    fmt.Printf("%s\n", data)

输出:

{"Title":"Casablanca","released":1942,"Actors":["Humphrey Bogart","Ingrid Bergman"]}

2. 字典序列化

一个字典要想序列化成- JSON 格式,它的 key 必须是字符串。

以下是一个例子:

info := map[string]int{    "width":  1280,    "height": 720,}data, err := json.MarshalIndent(info, "", " ")if err != nil {    log.Fatalf("JSON marshaling failed: %s", err)}fmt.Printf("%s\n", data)

输出:

{
 "height": 720,
 "width": 1280
}

MarshalIndent

3. 切片序列化

直接看一个例子:

type Movie struct {    Title  string    Year   int  `json:"released"`    Color  bool `json:"color,omitempty"`    Actors []string}var movies = []Movie{    {        Title:  "Casablanca",        Year:   1942,        Color:  false,        Actors: []string{"Humphrey Bogart", "Ingrid Bergman"},    },    {        Title:  "Cool Hand Luke",        Year:   1967,        Color:  true,        Actors: []string{"Paul Newman"},    },    {        Title:  "Bullitt",        Year:   1968,        Color:  true,        Actors: []string{"Steve McQueen", "Jacqueline Bisset"},    },}data, err := json.MarshalIndent(movies, "", " ")if err != nil {    log.Fatalf("JSON marshaling failed: %s", err)}fmt.Printf("%s\n", data)

输出:

[
 {
  "Title": "Casablanca",
  "released": 1942,
  "Actors": [
   "Humphrey Bogart",
   "Ingrid Bergman"
  ]
 },
 {
  "Title": "Cool Hand Luke",
  "released": 1967,
  "color": true,
  "Actors": [
   "Paul Newman"
  ]
 },
 {
  "Title": "Bullitt",
  "released": 1968,
  "color": true,
  "Actors": [
   "Steve McQueen",
   "Jacqueline Bisset"
  ]
 }
]

反序列化

Unmarshal
func Unmarshal(data []byte, v interface{}) error

1. 明确知道 JSON 格式

我们要先将 JSON 格式表示为一个确定的类型。

1.如下的 JSON 格式:

{    "name": "Awesome 4K",    "resolutions": [        {            "width": 1280,            "height": 720        },        {            "width": 1920,            "height": 1080        },        {            "width": 3840,            "height": 2160        }    ]}

我们可以用如下结构体来表示它:

struct {    Name        string    Resolutions []struct {        Width  int        Height int    }}

2.如下的 JSON 格式:

{ "height": 720, "width": 1280}
map[string]int

3.如下的 JSON 格式:

[    {        "width": 1280,        "height": 720    },    {        "width": 1920,        "height": 1080    },    {        "width": 3840,        "height": 2160    }]
[]map[string]int

不管怎样,一个确定的JSON格式总是可以使用切片、结构体或字典来表示。

之后就可以执行反序列化了:

var jsonBlob = []byte(`    [        {            "width": 1280,            "height": 720        },        {            "width": 1920,            "height": 1080,        },        {            "width": 3840,            "height": 2160        }    ]`)di := []map[string]int{}err = json.Unmarshal(jsonBlob, &di)if err != nil {    fmt.Println("error:", err)}fmt.Printf("%+v\n", di)

输出

[map[height:720 width:1280] map[height:1080 width:1920] map[height:2160 width:3840]]

2. 无法确定 JSON 格式

interface{}map[string]interface{}[]interface{}interface{}

具体看一个示例:

package mainimport (    "encoding/json"    "fmt")func main() {    var jsonBlob = []byte(`        {            "name": "Awesome 4K",            "price": 1999.9,            "resolutions": [                {                    "width": 1280,                    "height": 720                },                {                    "width": 1920,                    "height": 1080                },                {                    "width": 3840,                    "height": 2160                }            ]        }    `)    var d interface{}    err := json.Unmarshal(jsonBlob, &d)    if err != nil {        fmt.Println("error:", err)    }    fmt.Println(d)    m := d.(map[string]interface{})    for k, v := range m {        switch vv := v.(type) {        case string:            fmt.Println(k, "is string", vv)        case float64:            fmt.Println(k, "is float64", vv)        case []interface{}:            fmt.Println(k, "is an array:")            for i, u := range vv {                fmt.Println(i, u)            }        default:            fmt.Println(k, "is of a type I don't know how to handle")        }    }}

输出:

map[name:Awesome 4K price:1999.9 resolutions:[map[height:720 width:1280] map[height:1080 width:1920] map[height:2160 width:3840]]]
resolutions is an array:
0 map[height:720 width:1280]
1 map[height:1080 width:1920]
2 map[height:2160 width:3840]
name is string Awesome 4K
price is float64 1999.9

原文链接:https://blog.csdn.net/woay2008/article/details/120892096