json包

现代的语言都会支持json这种轻量的序列化方式。在golang中使用encoding/json来支持json的各个操作。

序列化方法

json序列化方法是Marshal函数,函数签名是

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

反序列化方法

json序列化方法是Unmarshal函数,函数签名是

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

用于json的Struct Tag

json序列号和反序列化只针对可见字段,对于不可见字段这两个过程都会直接忽略。 使用omitempty来处理空值,使用-忽略字段。

package main import ( "encoding/json" "fmt" ) func main() { type Stu struct { Name string `json:"name"` Age int `json:"age"` No string `json:"no,omitempty"` Gender int `json:"-"` group int //这个字段不参与序列化 } stu := Stu{ Name: "wida", Age: 35, No: "8001", Gender: 0, group: 88, } b, _ := json.Marshal(&stu) fmt.Println(string(b)) var stu1 Stu json.Unmarshal(b, &stu1) fmt.Printf("%+v", stu1) }
$ go run main.go {"name":"wida","age":35,"no":"8001"} {Name:wida Age:35 No:8001 Gender:0 group:0}

定制序列化和反序列化方式

encoding/json包中定义了MarshalerUnmarshaler

type Marshaler interface { MarshalJSON() ([]byte, error) } type Unmarshaler interface { UnmarshalJSON([]byte) error }

如果一个类型实现了这两个接口就有实现自定义的json序列化和反序列化。

看下官方文档的一个例子:

package main import ( "encoding/json" "fmt" "log" "strings" ) type Animal int const ( Unknown Animal = iota Gopher Zebra ) func (a *Animal) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } switch strings.ToLower(s) { default: *a = Unknown case "gopher": *a = Gopher case "zebra": *a = Zebra } return nil } func (a Animal) MarshalJSON() ([]byte, error) { var s string switch a { default: s = "unknown" case Gopher: s = "gopher" case Zebra: s = "zebra" } return json.Marshal(s) } func main() { blob := `["gopher","armadillo","zebra","unknown","gopher","bee","gopher","zebra"]` var zoo []Animal if err := json.Unmarshal([]byte(blob), &zoo); err != nil { log.Fatal(err) } census := make(map[Animal]int) for _, animal := range zoo { census[animal] += 1 } fmt.Printf("Zoo Census:\n* Gophers: %d\n* Zebras: %d\n* Unknown: %d\n", census[Gopher], census[Zebra], census[Unknown]) }