golang的json序列化
json就是简单的数据交换格式,语法类似javascript的对象和列表,是最常见的后端和运行在网页上的js之间的通信格式。
encoding:
编码json数据需要使用到Marshal()函数。
func Marshal(v interface{}) ([]byte, error) type Message struct { Name string Body string Time int64 } m := Message{"Alice", "Hello", 1294706395881547000} b, err := json.Marshal(m) b == []byte(`{"Name":"Alice","Body":"Hello","Time":1294706395881547000}`)
上面的代码就是讲一个Message对象编码成json的格式。json格式的显示是[]byte类型的。
decoding:
解码json格式的数据使用到的是Unmarshal()函数。
func Unmarshal(data []byte, v interface{}) error var m Message err := json.Unmarshal(b, &m)
Unmarshal()接受的是[]byte类型的json数据,和这个数据要返回的结构体的指针。
在Unmarshal()函数中。只能识别在m这个结构体中所拥有的属性字段。不存在的将会被忽略。
通用的json接口:interface{}
任意的go类型都实现了空接口interface{}
var i interface{} i = "a string" i = 2011 i = 2.777
可以使用断言来判断它的实现类型
r := i.(float64) fmt.Println("the circle‘s area", math.Pi*r*r)
如果不知道实现的类型,可以使用swtich case来片判断
switch v := i.(type) { case int: fmt.Println("twice i is", v*2) case float64: fmt.Println("the reciprocal of i is", 1/v) case string: h := len(v) / 2 fmt.Println("i swapped by halves is", v[h:]+v[:h]) default: // i isn‘t one of the types above }
json包使用map[string]interface{}和[]interface{}来存储任意的json对象和数组。go的类型和json的类型对应如下:
bool
for JSON booleans,
float64
for JSON numbers,
string
for JSON strings,
nil
for JSON null.
解码任意数据data
假设b中存储的书json数据
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
当不知道这个数据的结构体的时候,可以使用Unmarshal()来将它解码成一个interface{}的值。
var f interface{} err := json.Unmarshal(b, &f)
f现在的数据结构就是一个map[string]interface{}
f = map[string]interface{}{ "Name": "Wednesday", "Age": 6, "Parents": []interface{}{ "Gomez", "Morticia", }, }
可以使用断言f的底层接口来访问这些数据
m := f.(map[string]interface{})
然后遍历这个map,利用switch case来断言底层的类型
for k, v := range m { switch vv := v.(type) { case string: fmt.Println(k, "is string", vv) case int: fmt.Println(k, "is int", vv) case []interface{}: fmt.Println(k, "is an array:") for i, u := range vv { fmt.Println(i, u) } default: fmt.Println(k, "is of a type I don‘t know how to handle") } }
Reference Types:
type FamilyMember struct { Name string Age int Parents []string } var m FamilyMember err := json.Unmarshal(b, &m)
将b中的[]byte数据编码到FamilyMember结构体中去,
Let‘s define a Go type to contain the data from the previous example:
type FamilyMember struct { Name string Age int Parents []string } var m FamilyMember err := json.Unmarshal(b, &m)
Unmarshaling that data into a FamilyMember
value works as expected, but if we look closely we can see a remarkable thing has happened. With the var statement we allocated a FamilyMember
struct, and then provided a pointer to that value toUnmarshal
, but at that time the Parents
field was a nil
slice value. To populate the Parents
field, Unmarshal
allocated a new slice behind the scenes. This is typical of how Unmarshal
works with the supported reference types (pointers, slices, and maps).
Consider unmarshaling into this data structure:
type Foo struct { Bar *Bar }
If there were a Bar
field in the JSON object, Unmarshal
would allocate a new Bar
and populate it. If not, Bar
would be left as a nil
pointer.
From this a useful pattern arises: if you have an application that receives a few distinct message types, you might define "receiver" structure like
type IncomingMessage struct { Cmd *Command Msg *Message }
and the sending party can populate the Cmd
field and/or the Msg
field of the top-level JSON object, depending on the type of message they want to communicate. Unmarshal
, when decoding the JSON into an IncomingMessage
struct, will only allocate the data structures present in the JSON data. To know which messages to process, the programmer need simply test that either Cmd
or Msg
is not nil
.
Streaming Encoders and Decoders
The json package provides Decoder
and Encoder
types to support the common operation of reading and writing streams of JSON data. The NewDecoder
and NewEncoder
functions wrap the io.Reader
and io.Writer
interface types.
func NewDecoder(r io.Reader) *Decoder func NewEncoder(w io.Writer) *Encoder
Here‘s an example program that reads a series of JSON objects from standard input, removes all but the Name
field from each object, and then writes the objects to standard output:
package main import ( "encoding/json" "log" "os" ) func main() { dec := json.NewDecoder(os.Stdin) enc := json.NewEncoder(os.Stdout) for { var v map[string]interface{} if err := dec.Decode(&v); err != nil { log.Println(err) return } for k := range v { if k != "Name" { delete(v, k) } } if err := enc.Encode(&v); err != nil { log.Println(err) } } }
Due to the ubiquity of Readers and Writers, these Encoder
and Decoder
types can be used in a broad range of scenarios, such as reading and writing to HTTP connections, WebSockets, or files.
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。