序列化
需要注意的是:只有 struct 中支持导出的 field 才能被 JSON package 序列化,即首字母大写的 field。
JSON 对象一般都是小写表示,Marshal 之后 JSON 对象的首字母依然是大写,如果序列化之后名称想要改变如何实现,答案就是 struct tags。
type MyStruct struct {
SomeField string `json:"some_field"`
}
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”}
//JSON format
js, _ := json.Marshal(vc)
fmt.Println(string(js))
//using an encoder
file, _ := os.OpenFile("vcard.json", os.O_CREATE|os.O_WRONLY, 0666)
defer file.Close()
enc := json.NewEncoder(file)
err := enc.Encode(vc)
if err != nil {
log.Println("error in encoding json")
}
}
<a name="pSYsj"></a>
#### 反序列化
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 字段去尝试匹配目标结构字段;但是只有真正匹配上的字段才会填充数据。字段没有匹配不会报错,而是直接忽略掉。
<a name="rDkp6"></a>
#### 解码任意的数据:
json 包使用 map[string]interface{} 和 []interface{} 储存任意的 JSON 对象和数组;其可以被反序列化为任何的 JSON blob 存储到接口值中。
```go
var f interface{}
err := json.Unmarshal(b, &f)
f 指向的值是一个 map,key 是一个字符串,value 是自身存储作为空接口类型的值:
map[string]interface{} {
"Name": "Wednesday",
"Age": 6,
"Parents": []interface{} {
"Gomez",
"Morticia",
},
}
要访问这个数据,我们可以使用类型断言
m := f.(map[string]interface{})
编码和解码流
json 包提供 Decoder 和 Encoder 类型来支持常用 JSON 数据流读写。NewDecoder 和 NewEncoder 函数分别封装了 io.Reader 和 io.Writer 接口。
func NewDecoder(r io.Reader) *Decoder
func NewEncoder(w io.Writer) *Encoder
package main
import (
"bufio"
"encoding/json"
"fmt"
"os"
)
func main() {
var f interface{}
jsonFile, err := os.Open("vcard.json")
if err != nil {
fmt.Println(err)
}
reader := bufio.NewReader(jsonFile)
decoder := json.NewDecoder(reader)
err = decoder.Decode(&f)
if err != nil {
fmt.Println(err)
}
fmt.Println(f)
}