序列化

需要注意的是:只有 struct 中支持导出的 field 才能被 JSON package 序列化,即首字母大写的 field
JSON 对象一般都是小写表示,Marshal 之后 JSON 对象的首字母依然是大写,如果序列化之后名称想要改变如何实现,答案就是 struct tags

  1. type MyStruct struct {
  2. SomeField string `json:"some_field"`
  3. }

SomeField 序列化之后会变成 some_field。

  • json.Marshal() 的函数签名是 func Marshal(v interface{}) ([]byte, error)
  • 出于安全考虑,在 web 应用中最好使用 json.MarshalforHTML() 函数
  • json.NewEncoder() 的函数签名是 func NewEncoder(w io.Writer) *Encoder,返回的Encoder类型的指针可调用方法 Encode(v interface{}),将数据对象 v 的json编码写入 io.Writer w 中。 ```go package main

import ( “encoding/json” “fmt” “log” “os” )

type Address struct { Type string City string Country string }

type VCard struct { FirstName string LastName string Addresses []*Address Remark string }

func main() { pa := &Address{“private”, “Heze”, “China”} wa := &Address{“work”, “Qingdao”, “China”} vc := VCard{“Jack”, “ma”, []*Address{pa, wa}, “none”}

  1. //JSON format
  2. js, _ := json.Marshal(vc)
  3. fmt.Println(string(js))
  4. //using an encoder
  5. file, _ := os.OpenFile("vcard.json", os.O_CREATE|os.O_WRONLY, 0666)
  6. defer file.Close()
  7. enc := json.NewEncoder(file)
  8. err := enc.Encode(vc)
  9. if err != nil {
  10. log.Println("error in encoding json")
  11. }

}

  1. <a name="pSYsj"></a>
  2. #### 反序列化
  3. UnMarshal() 的函数签名是 func Unmarshal(data []byte, v interface{}) error 把 JSON 解码为数据结构。<br />vc 编码后的数据为 js ,对其解码时,我们首先创建结构 VCard 用来保存解码的数据:var v VCard 并调用 json.Unmarshal(js, &v),解析 []byte 中的 JSON 数据并将结果存入指针 &v 指向的值。<br />虽然反射能够让 JSON 字段去尝试匹配目标结构字段;但是只有真正匹配上的字段才会填充数据。字段没有匹配不会报错,而是直接忽略掉。
  4. <a name="rDkp6"></a>
  5. #### 解码任意的数据:
  6. json 包使用 map[string]interface{} 和 []interface{} 储存任意的 JSON 对象和数组;其可以被反序列化为任何的 JSON blob 存储到接口值中。
  7. ```go
  8. var f interface{}
  9. err := json.Unmarshal(b, &f)

f 指向的值是一个 map,key 是一个字符串,value 是自身存储作为空接口类型的值:

  1. map[string]interface{} {
  2. "Name": "Wednesday",
  3. "Age": 6,
  4. "Parents": []interface{} {
  5. "Gomez",
  6. "Morticia",
  7. },
  8. }

要访问这个数据,我们可以使用类型断言

  1. m := f.(map[string]interface{})

编码和解码流

json 包提供 Decoder 和 Encoder 类型来支持常用 JSON 数据流读写。NewDecoder 和 NewEncoder 函数分别封装了 io.Reader 和 io.Writer 接口。

  1. func NewDecoder(r io.Reader) *Decoder
  2. func NewEncoder(w io.Writer) *Encoder
  1. package main
  2. import (
  3. "bufio"
  4. "encoding/json"
  5. "fmt"
  6. "os"
  7. )
  8. func main() {
  9. var f interface{}
  10. jsonFile, err := os.Open("vcard.json")
  11. if err != nil {
  12. fmt.Println(err)
  13. }
  14. reader := bufio.NewReader(jsonFile)
  15. decoder := json.NewDecoder(reader)
  16. err = decoder.Decode(&f)
  17. if err != nil {
  18. fmt.Println(err)
  19. }
  20. fmt.Println(f)
  21. }