JSON 序列化和反序列化 In Go

Posted 第二范式

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSON 序列化和反序列化 In Go相关的知识,希望对你有一定的参考价值。

上一节我们介绍了 xml 的使用,其实对于数据的序列化和反序列化还有一种更为常见的方式,那就是 JSON,尤其是在 http, rpc 的微服务调用中。

基础语法

在 Go 中我们主要使用官方的 encoding/json 包对 JSON 数据进行序列化和反序列化,主要使用方法有:

  • 序列化:

 
   
   
 
  1. func Marshal(v interface{}) ([]byte, error)

  • 反序列化:

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

简单例子:

 
   
   
 
  1. package main

  2. import (

  3.    "encoding/json"

  4.    "fmt"

  5. )

  6. func main() {

  7.    var (

  8.        data  = `1`

  9.        value int

  10.    )

  11.    err1 := json.Unmarshal([]byte(data), &value)

  12.    fmt.Println("Unmarshal error is:", err1)

  13.    fmt.Printf("Unmarshal value is: %T, %d \n", value, value)

  14.    value2, err2 := json.Marshal(value)

  15.    fmt.Println("Marshal error is:", err2)

  16.    fmt.Printf("Marshal value is: %s \n", string(value2))

  17. }

当我们运行代码的时候可以得到如下输出结果:

 
   
   
 
  1. Unmarshal error is: <nil>

  2. Unmarshal value is: int, 1

  3. Marshal error is: <nil>

  4. Marshal value is: 1

在这个例子中,我们使用 UnmarshalMarshal 将一个整数的 JSON 二进制转化为 go int 数据。

注意:在实际应用中,我们在序列化和反序列化的时候,需要检查函数返回的 err, 如果 err 不为空,表示数据转化失败。

例如:我们把上面例子中 value 类型由 int 修改为 string 后再次运行代码,你将得到 Unmarshalerroris:json:cannot unmarshal numberintoGovalue of typestring 的错误提醒。

数据对应关系

JSON 和 Go 数据类型对照表:

类型 JSON Go
bool true, false true, false
string "a" string("a")
整数 1 int(1), int32(1), int64(1) ...
浮点数 3.14 float32(3.14), float64(3.14) ...
数组 [1,2] [2]int{1,2}, []int{1, 2}
对象 Object {"a": "b"} map[string]string, struct
未知类型 ... interface{}

例如:

 
   
   
 
  1. package main

  2. import (

  3.    "encoding/json"

  4.    "fmt"

  5. )

  6. func main() {

  7.    var (

  8.        d1 = `false`

  9.        v1 bool

  10.    )

  11.    json.Unmarshal([]byte(d1), &v1)

  12.    printHelper("d1", v1)

  13.    var (

  14.        d2 = `2`

  15.        v2 int

  16.    )

  17.    json.Unmarshal([]byte(d2), &v2)

  18.    printHelper("d2", v2)

  19.    var (

  20.        d3 = `3.14`

  21.        v3 float32

  22.    )

  23.    json.Unmarshal([]byte(d3), &v3)

  24.    printHelper("d3", v3)

  25.    var (

  26.        d4 = `[1,2]`

  27.        v4 []int

  28.    )

  29.    json.Unmarshal([]byte(d4), &v4)

  30.    printHelper("d4", v4)

  31.    var (

  32.        d5 = `{"a": "b"}`

  33.        v5 map[string]string

  34.        v6 interface{}

  35.    )

  36.    json.Unmarshal([]byte(d5), &v5)

  37.    printHelper("d5", v5)

  38.    json.Unmarshal([]byte(d5), &v6)

  39.    printHelper("d5(interface{})", v6)

  40. }

  41. func printHelper(name string, value interface{}) {

  42.    fmt.Printf("%s Unmarshal value is: %T, %v \n", name, value, value)

  43. }

运行代码我们可以得到如下输出结果:

 
   
   
 
  1. d1 Unmarshal value is: bool, false

  2. d2 Unmarshal value is: int, 2

  3. d3 Unmarshal value is: float32, 3.14

  4. d4 Unmarshal value is: []int, [1 2]

  5. d5 Unmarshal value is: map[string]string, map[a:b]

  6. d5(interface{}) Unmarshal value is: map[string]interface {}, map[a:b]

自定义数据类型

除了使用上面基础数据外,对于那些比较复杂的数据集合(Object),我们还可以使用自定义数据类型 struct 来转化。

  • Go 中关于 JSON 转化字段名的对应语法为:

 
   
   
 
  1. Field int `json:"myName"`

  • 如果我们想忽略那些空值的字段,我们可以使用 omitempty 选项:

 
   
   
 
  1. Field int `json:"myName,omitempty"`

  • 如果我们想忽略特定字段:

 
   
   
 
  1. Field int `json:"-"`

组合示例:

 
   
   
 
  1. type A struct {

  2.    A int     `json:"k"`

  3.    B string  `json:"b,omitempty"`

  4.    C float64 `json:"-"`

  5. }

实战练习

假如我们有这样一段 JSON 数据,它表示一个学生的考试成绩,下面我们就来看看在 Go 中如何序列化和反序列化。

  • 数据准备:

 
   
   
 
  1. # data.json

  2. {

  3.    "id": 1,

  4.    "name": "小红",

  5.    "results": [

  6.        {

  7.            "name": "语文",

  8.            "score": 90

  9.        },

  10.        {

  11.            "name": "数学",

  12.            "score": 100

  13.        }

  14.    ]

  15. }

  • 反序列化:

 
   
   
 
  1. package main

  2. import (

  3.    "encoding/json"

  4.    "fmt"

  5.    "io/ioutil"

  6. )

  7. type Result struct {

  8.    Name  string  `json:"name"`

  9.    Score float64 `json:"score"`

  10. }

  11. type Student struct {

  12.    Id int `json:"id"`

  13.    Name    string   `json:"name"`

  14.    Results []Result `json:"results"`

  15. }

  16. func main() {

  17.    dat, _ := ioutil.ReadFile("data.json")

  18.    var s Student

  19.    json.Unmarshal(dat, &s)

  20.    fmt.Printf("Student's result is: %v\n", s)

  21. }

运行代码输出结果为:

 
   
   
 
  1. Student's result is: {1 小红 [{语文 90} {数学 100}]}

  • 序列化:

 
   
   
 
  1. package main

  2. import (

  3.    "encoding/json"

  4.    "io/ioutil"

  5. )

  6. type Result struct {

  7.    Name  string  `json:"name"`

  8.    Score float64 `json:"score"`

  9. }

  10. type Student struct {

  11.    Id int `json:"id"`

  12.    Name    string   `json:"name"`

  13.    Results []Result `json:"results"`

  14. }

  15. func main() {

  16.    s := Student{

  17.        Id:   1,

  18.        Name: "小红",

  19.        Results: []Result{

  20.            Result{

  21.                Name:  "语文",

  22.                Score: 90,

  23.            },

  24.            Result{

  25.                Name:  "数学",

  26.                Score: 100,

  27.            },

  28.        },

  29.    }

  30.    dat, _ := json.Marshal(s)

  31.    ioutil.WriteFile("data2.json", dat, 0755)

  32. }

当我们运行代码后,打开 data2.json 文件,将看到如下内容:

 
   
   
 
  1. {

  2.    "id": 1,

  3.    "name": "小红",

  4.    "results": [

  5.        {

  6.            "name": "语文",

  7.            "score": 90

  8.        },

  9.        {

  10.            "name": "数学",

  11.            "score": 100

  12.        }

  13.    ]

  14. }


以上是关于JSON 序列化和反序列化 In Go的主要内容,如果未能解决你的问题,请参考以下文章

Go语言 Marshal 序列化和反序列化

Go读写文件

csharp 此代码演示了json序列化和反序列化的4种方法

ASP.NET 中JSON 的序列化和反序列化

ASP.NET中JSON的序列化和反序列化

ASP.NET中JSON的序列化和反序列化