go json操作

go语言学习之json操作。

go数据类型和json的类型对应关系图

  • bool类型 – JSON的Boolean
  • 整数,浮点数等数值类型 – JSON的Number
  • string – JSON的字符串(带”“引号)
  • struct – JSON的Object (再根据各个成员的类型递归打包)
  • 数组或切片 – JSON的Array
  • []byte – 会先进行base64编码然后转换为JSON字符串
  • map – JSON的Object。key必须是string
  • interface{} – 按照内部的实际类型进行转换
  • nil – JSON的null
  • channel,func等类型 – 返回UnsupportedTypeError

Marshal和Unmarshal函数

常见的Marshal使用方式是,结构体转json

    type Student struct {
        Name string     `json:"name"`  //通过标签的方式配置struck变量与json key对应关系
        Age  int        `json:"age"`
        Sex  string     `json:"sex"`
    }
    func main() {
        var stu = Student{"dtc", 22, "boy"}
        //将结构体封装成json格式,并返回[]byte
        j, err := json.Marshal(stu)
        if err != nil {
            fmt.Errorf("Marshal Error %v", err)
        }
        fmt.Println(string(j))
    }

output: {"Name":"dtc","Age":22,"Sex":"boy"}

结构体中大写开头的变量才可以被json处理(当未使用标签的时候),小写开头不会被处理。

     type Student struct {
        Name string    
        AgE  int                   // json key `age`无法识别
        sex  string                // 开头小写无法识别
        high string   `json:"-"`   // 设置-标签,忽略这个字段 
    }

通过UnMarshal解析json为struct

    type Student struct {
        Name string `json:"stu_name"`
        Age  int    `json:"stu_age"`
        Sex  string `json:"stu_sex"`
    }

    func main() {
        str := []byte(`{"stu_name":"hiehie","stu_age":22,"stu_sex":"girl"}`)
        var stu Student
        err := json.Unmarshal(str, &stu)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(stu)
    }
    output:  {hiehie 22 girl}

转换接口

Marshal(v interface{}) 在调用时,会先判断v参数是否实现json.Marshaler或者 encoding.Marshaler 接口,如果满足,则会调用这两个接口来进行转换(如果两个都满足,优先调用json.Marshaler)。这两个接口定义如下:

    // json.Marshaler 
    type Marshaler interface {
        MarshalJSON() ([]byte, error)
    }
    
    // encoding.TextMarshaler
    type TextMarshaler interface {
        MarshalText() (text []byte, err error)
    }

UnMarshal(v interface{})在调用时,会先判断参数v是否实现json.Unmarshaler和encoding.TextUnmarshaler来调用相应函数(若两个函数都存在,则优先调用UnmarshalJSON)。这两个接口定义如下:

    // json.Unmarshaler
    type Unmarshaler interface {
        UnmarshalJSON([]byte) error
    }
    
    // encoding.TextUnmarshaler
    type TextUnmarshaler interface {
        UnmarshalText(text []byte) error
    }

可以通过对结构体实现marshalJSON和UnmarshalJSON接口实现自己编码解码。

参考链接

https://studygolang.com/articles/10581
https://blog.csdn.net/u011304970/article/details/70769949

总结

使用go json时注意使用标签防止json解析错误。
结构体变量定义尽量规范。

Life is more than the present.