golang实现json序列化和反序列化

将对象转换成二进制流的过程叫做序列化
将二进制流转换成对象的过程叫做反序列化

那么如何实现一个结构体序列化和反序列化呢?

JSON序列化和反序列化

在golang中,json的序列化和反序列化用到的是encoding/json包,提供了一系列相关的方法用于处理json。

自定义Go Json的序列化方法

参考: [译]自定义Go Json的序列化方法 | 鸟窝

如果你为类型实现了MarshalJSON() ([]byte, error)UnmarshalJSON(b []byte) error方法,那么这个类型在序列化反序列化时将采用你定制的方法。

临时为一个struct增加一个字段,可以考虑采用如下的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package main

import (
"encoding/json"
"os"
"time"
)

type MyUser struct {
ID int64 `json:"id"`
Name string `json:"name"`
LastSeen time.Time `json:"lastSeen"`
}

func (u *MyUser) MarshalJSON() ([]byte, error) {
type Alias MyUser
return json.Marshal(&struct {
LastSeen int64 `json:"lastSeen"`
*Alias
}{
Alias: (*Alias)(u),
LastSeen: u.LastSeen.Unix(),
})
}

func (u *MyUser) UnmarshalJSON(data []byte) error {
type Alias MyUser

aux := &struct {
LastSeen int64 `json:"lastSeen"`
*Alias
}{
Alias: (*Alias)(u),
}

if err := json.Unmarshal(data, &aux); err != nil {
return err
}

u.LastSeen = time.Unix(aux.LastSeen, 0)
return nil
}

// https://colobu.com/2020/03/19/Custom-JSON-Marshalling-in-Go/
// 自定义json序列化方法
func main() {
_ = json.NewEncoder(os.Stdout).Encode(&MyUser{
1, "dillon", time.Now(),
})
}

参考:

  1. JSON and Go - The Go Blog

  2. json - The Go Programming Language

  3. [译]自定义Go Json的序列化方法 | 鸟窝