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包中定义了Marshaler和Unmarshaler
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])
}