這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1. 簡介
JSON(JavaScript Object Notation)是一種輕量級的資料交換格式。其文法上類似於 JavaScript 的對象和列表。最常用於 web 後端之間的通訊和在瀏覽器中運行 JavaScript 程式,但是其它地方也大量使用。其首頁:json.org,提供了一個非常清晰和簡明定義的標準。
使用 json 包 可以很容易的在 GO 程式中讀寫 JSON 資料。
2. 編碼
使用 Marshal 函數產生 JSON 資料。
func Marshal(v interface{}) ([]byte, error)
給定 GO 資料的結構體:Message,
type Message struct { Name string Body string Time int64}
然後擷取 Message 的一個執行個體。
m := Message{"Alice", "Hello", 1294706395881547000}
使用 json.Marshal 獲得一個 JSON 格式的 m。
b, err := json.Marshal(m)
如果一切順利,err 將會為 nil,b 將會是一個包含 JSON 資料的 []byte
b == []byte(`{"Name":"Alice","Body":"Hello","Time":1294706395881547000}`)
只有當資料結構體能被表示成合法的 JSON 時,才會被編碼。
- JSON 對象只支援 strings 類型作為鍵名;必須使用 map[string]T來編碼成 Go map 類型(其中
T 是任意一種 json 包支援的 Go 類型)。
- Channel,complex 和函數類型不能被編碼。
- 不支援迴圈的資料結構,將會導致
Marshal 進入死迴圈。
- 指標將被編碼成它們指向的值(或’null’,如果指標是零)。
json包只訪問公開欄位的結構體類型(以大寫字母開頭的那些),因此只有公開欄位的結構體會出現在 JSON 輸出中。
範例程式碼 :
package mainimport ( "encoding/json" "fmt" "os")func main() { type ColorGroup struct { ID int Name string Colors []string } group := ColorGroup{ ID: 1, Name: "Reds", Colors: []string{"Crimson", "Red", "Ruby", "Maroon"}, } b, err := json.Marshal(group) if err != nil { fmt.Println("error:", err) } os.Stdout.Write(b)}
3. 解碼
使用 Unmarshal 函數解析 JSON 資料。
func Unmarshal(data []byte, v interface{}) error
首先必須建立一個存放解析資料的地方。
var m Message
然後調用 json.Unmarshal,傳入一個包含 JSON 資料的 []byte 和一個指標 m。
err := json.Unmarshal(b, &m)
如果 b 包含適合 m 的有效 JSON 資料,那麼調用 err 將會是nil,然後資料將會從 b 儲存到結構體 m 中,就像賦值:
m = Message{ Name: "Alice", Body: "Hello", Time: 1294706395881547000,}
使用 Unmarshal 時,如何定義用於儲存解碼資料的欄位?對於給定的鍵 "Foo",Unmarshal 將會瀏覽目標結構體來尋找相應欄位。(按優先順序排列)
- 一個標籤為
"Foo" 的公開欄位(更多結構體標籤查看 Go spec),
- 一個名稱為
"Foo" 的公開欄位,或
- 一個名稱為
"FOO" 或 "FoO" 或一些其它的不區分大小寫匹配 "Foo" 的公開欄位。
如果 JSON 資料的結構體與 Go 類型不完全符合?
b := []byte(`{"Name":"Bob","Food":"Pickle"}`)var m Messageerr := json.Unmarshal(b, &m)
Unmarshal 只解析目標類型中定義的欄位。在這個例子中,只有 m 的 Name 欄位會被解析,而 Food 欄位將被忽略。當只希望從大的 JSON 資料中選擇少量特定欄位時,該行為非常實用。這也意味著任何目標結構體的私人欄位將不受 Unmarshal 影響。
範例程式碼 :
package mainimport ( "encoding/json" "fmt")func main() { var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`) type Animal struct { Name string Order string } var animals []Animal err := json.Unmarshal(jsonBlob, &animals) if err != nil { fmt.Println("error:", err) } fmt.Printf("%+v", animals)}
4. 筆記
- 自訂輸出的 JSON 資料的鍵名,在欄位類型後使用反單引號
json:" ":
type Animal struct { Name string `json:"name"` Order string }
type Animal struct { Name string `json:"-"` Order string }
參考資料
Go 部落格:http://blog.golang.org/json-and-go
Go 程式設計語言 json 包:https://golang.org/pkg/encoding/json/
rgyq 部落格:http://rgyq.blog.163.com/blog/static/316125382013934153244/