@目錄
- Marshal
- Unmarshal
- 處理json物件
json包實作了json物件的編解碼,參見RFC 4627,Json物件和go型別的映射關系主要通過Marshal和Unmarshal函式實作
Marshal
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物件,每一個匯出欄位變成該物件的一個成員,除非:
- 欄位的標簽是"-"
- 欄位是空值,而其標簽指定了omitempty選項
空值是false、0、""、nil指標、nil介面、長度為0的陣列、切片、映射,物件默認鍵字串是結構體的欄位名,但可以在結構體欄位的標簽里指定,結構體標簽值里的"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)
}
Unmarshal
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物件
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()
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/55016.html
標籤:Go
上一篇:這個dll的函式應該怎么呼叫?
下一篇:goweb-搭建服務
