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的類型對應如下:
boolfor JSON booleans,
float64for JSON numbers,
stringfor JSON strings,
nilfor 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結構體中去,首先給FamilyMember 分配內存,然后傳入一個指針到Unmarshal中去。但是屬性Parents是一個nil空值,unmarshal給這個slice分配一個新的塊。
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.
