@java
json包實現了json對象的編解碼,參見RFC 4627。Json對象和go類型的映射關係主要經過Marshal和Unmarshal函數實現json
func Marshal(v interface{}) ([]byte, error)
Marshal函數返回v的json編碼。數組
Marshal函數會遞歸的處理值。若是一個值實現了Marshaler接口切非nil指針,會調用其MarshalJSON方法來生成json編碼。nil指針異常並非嚴格必需的,但會模擬與UnmarshalJSON的行爲相似的必需的異常。瀏覽器
不然,Marshal函數使用下面的基於類型的默認編碼格式:數據結構
布爾類型編碼爲json布爾類型。函數
浮點數、整數和Number類型的值編碼爲json數字類型。編碼
字符串編碼爲json字符串。角括號"<"和">"會轉義爲"\u003c"和"\u003e"以免某些瀏覽器吧json輸出錯誤理解爲HTML。基於一樣的緣由,"&"轉義爲"\u0026"。代理
數組和切片類型的值編碼爲json數組,但[]byte編碼爲base64編碼字符串,nil切片編碼爲null。指針
結構體的值編碼爲json對象。每個導出字段變成該對象的一個成員,除非:
// 字段被本包忽略
Field int json:"-"
// 字段在json裏的鍵爲"myName"
Field int json:"myName"
// 字段在json裏的鍵爲"myName"且若是字段爲空值將在對象中省略掉
Field int json:"myName,omitempty"
// 字段在json裏的鍵爲"Field"(默認值),但若是字段爲空值會跳過;注意前導的逗號
Field int json:",omitempty"
"string"選項標記一個字段在編碼json時應編碼爲字符串。它只適用於字符串、浮點數、整數類型的字段。這個額外水平的編碼選項有時候會用於和javascript程序交互:
Int64String int64 json:",string"
若是鍵名是隻含有unicode字符、數字、美圓符號、百分號、連字符、下劃線和斜槓的非空字符串,將使用它代替字段名。
匿名的結構體字段通常序列化爲他們內部的導出字段就好像位於外層結構體中同樣。若是一個匿名結構體字段的標籤給其提供了鍵名,則會使用鍵名代替字段名,而不視爲匿名。
Go結構體字段的可視性規則用於供json決定那個字段應該序列化或反序列化時是通過修正了的。若是同一層次有多個(匿名)字段且該層次是最小嵌套的(嵌套層次則使用默認go規則),會應用以下額外規則:
1)json標籤爲"-"的匿名字段強行忽略,不做考慮;
2)json標籤提供了鍵名的匿名字段,視爲非匿名字段;
3)其他字段中若是隻有一個匿名字段,則使用該字段;
4)其他字段中若是有多個匿名字段,但壓平後不會出現衝突,全部匿名字段壓平;
5)其他字段中若是有多個匿名字段,但壓平後出現衝突,所有忽略,不產生錯誤。
對匿名結構體字段的管理是從go1.1開始的,在以前的版本,匿名字段會直接忽略掉。
映射類型的值編碼爲json對象。映射的鍵必須是字符串,對象的鍵直接使用映射的鍵。
指針類型的值編碼爲其指向的值(的json編碼)。nil指針編碼爲null。
接口類型的值編碼爲接口內保持的具體類型的值(的json編碼)。nil接口編碼爲null。
通道、複數、函數類型的值不能編碼進json。嘗試編碼它們會致使Marshal函數返回UnsupportedTypeError。
Json不能表示循環的數據結構,將一個循環的結構提供給Marshal函數會致使無休止的循環。
Example
func json_encode() { 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.Exit(1) } os.Stdout.Write(b) }
func Unmarshal(data []byte, v interface{}) error
Unmarshal函數解析json編碼的數據並將結果存入v指向的值。
Unmarshal和Marshal作相反的操做,必要時申請映射、切片或指針,有以下的附加規則:
要將json數據解碼寫入一個指針,Unmarshal函數首先處理json數據是json字面值null的狀況。此時,函數將指針設爲nil;不然,函數將json數據解碼寫入指針指向的值;若是指針自己是nil,函數會先申請一個值並使指針指向它。
要將json數據解碼寫入一個結構體,函數會匹配輸入對象的鍵和Marshal使用的鍵(結構體字段名或者它的標籤指定的鍵名),優先選擇精確的匹配,但也接受大小寫不敏感的匹配。
要將json數據解碼寫入一個接口類型值,函數會將數據解碼爲以下類型寫入接口:
Bool 對應JSON布爾類型
float64 對應JSON數字類型
string 對應JSON字符串類型
[]interface{} 對應JSON數組
map[string]interface{} 對應JSON對象
nil 對應JSON的null
若是一個JSON值不匹配給出的目標類型,或者若是一個json數字寫入目標類型時溢出,Unmarshal函數會跳過該字段並儘可能完成其他的解碼操做。若是沒有出現更加嚴重的錯誤,本函數會返回一個描述第一個此類錯誤的詳細信息的UnmarshalTypeError。
JSON的null值解碼爲go的接口、指針、切片時會將它們設爲nil,由於null在json裏通常表示「不存在」。 解碼json的null值到其餘go類型時,不會形成任何改變,也不會產生錯誤。
當解碼字符串時,不合法的utf-8或utf-16代理(字符)對不視爲錯誤,而是將非法字符替換爲unicode字符U+FFFD。
func json_decode() { 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) } r := ColorGroup{} err = json.Unmarshal(b, &r) if err != nil { fmt.Println("json.Unmarshal error : ", err) os.Exit(1) } fmt.Println(r) }
json對象 經過 map[string]interface{} 表示
func json_struct_and_map() { type People struct { Name string `json:"name"` Age int `json:"age"` Feature map[string]interface{} `json:feature` } var feature map[string]interface{} = make(map[string]interface{}) feature["personality"] = "cute" feature["Inner"] = "strength" p := People { Name : "ailumiyana", Age : 18, Feature : feature, } b, err := json.Marshal(p) if err != nil { fmt.Println("error:", err) os.Exit(1) } fmt.Println("encode : ") os.Stdout.Write(b) r := People{} err = json.Unmarshal(b, &r) if err != nil { fmt.Println("json.Unmarshal error : ", err) os.Exit(1) } fmt.Println("\ndecode : ") fmt.Println(r) //update if r.Feature == nil { r.Feature = make(map[string]interface{}) } r.Feature["fea"] = "warmth" b, err = json.Marshal(r) if err != nil { fmt.Println("error:", err) os.Exit(1) } fmt.Println("update : ") os.Stdout.Write(b) }
完整示例 :
package main import( "encoding/json" "fmt" "os" ) func json_encode() { 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.Exit(1) } os.Stdout.Write(b) } func json_decode() { 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) } r := ColorGroup{} err = json.Unmarshal(b, &r) if err != nil { fmt.Println("json.Unmarshal error : ", err) os.Exit(1) } fmt.Println(r) } func json_struct_and_map() { type People struct { Name string `json:"name"` Age int `json:"age"` Feature map[string]interface{} `json:feature` } var feature map[string]interface{} = make(map[string]interface{}) feature["personality"] = "cute" feature["Inner"] = "strength" p := People { Name : "ailumiyana", Age : 18, Feature : feature, } b, err := json.Marshal(p) if err != nil { fmt.Println("error:", err) os.Exit(1) } fmt.Println("encode : ") os.Stdout.Write(b) r := People{} err = json.Unmarshal(b, &r) if err != nil { fmt.Println("json.Unmarshal error : ", err) os.Exit(1) } fmt.Println("\ndecode : ") fmt.Println(r) //update if r.Feature == nil { r.Feature = make(map[string]interface{}) } r.Feature["fea"] = "warmth" b, err = json.Marshal(r) if err != nil { fmt.Println("error:", err) os.Exit(1) } fmt.Println("update : ") os.Stdout.Write(b) } func main(){ json_encode() json_decode() json_struct_and_map() }