零基础 go - 60(JSON序列化和反序列化)

9 阅读2分钟

JSON 介绍

  • JSON (javascript object notation),是一种轻量级的数据交换格式,易于人阅读和编写,

  • 易于机器解析和生成。它基于 JavaScript 语言的一个子集,但独立于语言,广泛用于数据存储和网络通信。

image.png

image.png

image.png

JSON序列化 json.Marshal()

  • 序列化时,如果希望重新定义反序列化后的字段名称,可以在结构体字段上使用 json 标签指定 JSON 中的字段名。

package main

import (

    "encoding/json"

    "fmt"

)

func main() {

    // 序列化一个结构体

    type Person struct {

        Name string `json:"name"` // 通过 json 标签指定序列化后的字段名为 "name"

        Age int `json:"age"`

    }

    p := Person{Name: "Alice", Age: 30}

    jsonData, err := json.Marshal(p)

    if err != nil {

        fmt.Println("Error serializing to JSON:", err)

        return

    }

    fmt.Println("Serialized JSON:", string(jsonData)) // 输出: {"name":"Alice","age":30}




    // 序列化一个 map

    m := map[string]interface{}{

        "name": "Bob",

        "age": 25,

        "scores": []int{90, 85, 92},

    }

    jsonData, err := json.Marshal(m)

    if err != nil {

        fmt.Println("Error serializing to JSON:", err)

        return

    }

    fmt.Println("Serialized JSON:", string(jsonData))





    // 序列化一个 slice

    s := []string{"apple", "banana", "cherry"}

    jsonData, err := json.Marshal(s)

    if err != nil {

        fmt.Println("Error serializing to JSON:", err)

        return

    }

    fmt.Println("Serialized JSON:", string(jsonData))




    // 序列化一个基本类型(一般不会这么做,但也是合法的)

    num := 42

    res, err := json.Marshal(num)

    if err != nil {

        fmt.Println("Error serializing to JSON:", err)

        return

    }

    fmt.Println("Serialized JSON:", string(res))

}

JSON反序列化 json.Unmarshal()

  • 反序列化需要注意目标数据结构必须与 JSON 数据的结构相匹配,否则会导致反序列化失败或数据丢失。

  • JSON 字符串需要使用转义字符 " 来表示双引号,或者使用反引号 ` 来包裹整个字符串以避免转义问题。


package main

import (

    "encoding/json"

    "fmt"

)

func main() {

    // 反序列化到一个结构体

    type Person struct {

        Name string `json:"name"`

        Age int `json:"age"`

    }

    jsonData := []byte("{\"name\": \"Alice\", \"age\": 30}") // 这里的 JSON 字符串需要使用转义字符 \" 来表示双引号,或者使用反引号 ` 来包裹整个字符串

    var p Person

    err := json.Unmarshal(jsonData, &p)

    if err != nil {

        fmt.Println("Error deserializing JSON:", err)

        return

    }

    fmt.Printf("Deserialized struct: %+v\n", p)





    // 反序列化到一个 map

    jsonData = []byte(`{"name": "Bob", "age": 25, "scores": [90, 85, 92]}`) // 这里的 JSON 字符串需要使用转义字符 \" 来表示双引号,或者使用反引号 ` 来包裹整个字符串

    var m map[string]interface{}

    err = json.Unmarshal(jsonData, &m)

    if err != nil {

        fmt.Println("Error deserializing JSON:", err)

        return

    }

    fmt.Printf("Deserialized map: %+v\n", m)




    // 反序列化到一个 slice

    jsonData = []byte(`["apple", "banana", "cherry"]`)

    var s []string

    err = json.Unmarshal(jsonData, &s)

    if err != nil {

        fmt.Println("Error deserializing JSON:", err)

        return

    }

    fmt.Printf("Deserialized slice: %+v\n", s)




    // 如果结构体字段类型与 JSON 数据不匹配,反序列化会失败

    jsonData = []byte(`{"name": "Charlie", "age": "thirty"}`) // 这里的 JSON 字符串需要使用转义字符 \" 来表示双引号,或者使用反引号 ` 来包裹整个字符串

    var p2 Person

    err = json.Unmarshal(jsonData, &p2) // 这里 age 字段是 string 类型,但 Person 结构体中定义为 int 类型,会导致反序列化失败

    if err != nil {

        fmt.Println("Error deserializing JSON with type mismatch:", err)

        return

    }

    fmt.Printf("Deserialized struct with type mismatch: %+v\n", p2)

}