?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
import "encoding/json"
Overview
Index
Examples
包json實現(xiàn)了RFC 4627中定義的JSON的編碼和解碼。JSON和Go值之間的映射在Marshal和Unmarshal函數(shù)的文檔中進行了描述。
有關此包的介紹,請參閱“JSON和Go”:https://golang.org/doc/articles/json_and_go.html
package mainimport ("encoding/json""fmt""log""strings")type Animal intconst ( Unknown Animal = iota Gopher Zebra)func (a *Animal) UnmarshalJSON(b []byte) error {var s stringif err := json.Unmarshal(b, &s); err != nil {return err}switch strings.ToLower(s) {default:*a = Unknowncase "gopher":*a = Gophercase "zebra":*a = Zebra}return nil}func (a Animal) MarshalJSON() ([]byte, error) {var s stringswitch a {default: s = "unknown"case Gopher: s = "gopher"case Zebra: s = "zebra"}return json.Marshal(s)}func main() { blob := `["gopher","armadillo","zebra","unknown","gopher","bee","gopher","zebra"]`var zoo []Animalif err := json.Unmarshal([]byte(blob), &zoo); err != nil { log.Fatal(err)} census := make(map[Animal]int)for _, animal := range zoo { census[animal] += 1} fmt.Printf("Zoo Census:\n* Gophers: %d\n* Zebras: %d\n* Unknown: %d\n", census[Gopher], census[Zebra], census[Unknown])}
func Compact(dst *bytes.Buffer, src []byte) error
func HTMLEscape(dst *bytes.Buffer, src []byte)
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
func Marshal(v interface{}) ([]byte, error)
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
func Unmarshal(data []byte, v interface{}) error
func Valid(data []byte) bool
type Decoder
func NewDecoder(r io.Reader) *Decoder
func (dec *Decoder) Buffered() io.Reader
func (dec *Decoder) Decode(v interface{}) error
func (dec *Decoder) More() bool
func (dec *Decoder) Token() (Token, error)
func (dec *Decoder) UseNumber()
type Delim
func (d Delim) String() string
type Encoder
func NewEncoder(w io.Writer) *Encoder
func (enc *Encoder) Encode(v interface{}) error
func (enc *Encoder) SetEscapeHTML(on bool)
func (enc *Encoder) SetIndent(prefix, indent string)
type InvalidUTF8Error
func (e *InvalidUTF8Error) Error() string
type InvalidUnmarshalError
func (e *InvalidUnmarshalError) Error() string
type Marshaler
type MarshalerError
func (e *MarshalerError) Error() string
type Number
func (n Number) Float64() (float64, error)
func (n Number) Int64() (int64, error)
func (n Number) String() string
type RawMessage
func (m RawMessage) MarshalJSON() ([]byte, error)
func (m *RawMessage) UnmarshalJSON(data []byte) error
type SyntaxError
func (e *SyntaxError) Error() string
type Token
type UnmarshalFieldError
func (e *UnmarshalFieldError) Error() string
type UnmarshalTypeError
func (e *UnmarshalTypeError) Error() string
type Unmarshaler
type UnsupportedTypeError
func (e *UnsupportedTypeError) Error() string
type UnsupportedValueError
func (e *UnsupportedValueError) Error() string
Decoder Decoder.Decode (Stream) Decoder.Token Indent Marshal RawMessage (Marshal) RawMessage (Unmarshal) Unmarshal Package (CustomMarshalJSON)
decode.go encode.go fold.go indent.go scanner.go stream.go tables.go tags.go
func Compact(dst *bytes.Buffer, src []byte) error
緊湊追加到JSON編碼的src中,而忽略空間字符。
func HTMLEscape(dst *bytes.Buffer, src []byte)
HTMLEscape將dst JSON編碼的src與字符串文字中的<,>,&U + 2028和U + 2029字符更改為\u003c,\u003e,\u0026,\u2028,\u2029,以便JSON安全嵌入HTML<script>標簽內(nèi)。由于歷史原因,Web瀏覽器不遵守<script>標簽內(nèi)的標準HTML轉(zhuǎn)義,因此必須使用替代的JSON編碼。
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
縮進附加到JSON編碼的src的縮進形式的dst。JSON對象或數(shù)組中的每個元素都以一個新的縮進行開始,該行以前綴開頭,隨后是根據(jù)縮進嵌套的一個或多個縮進副本。追加到dst的數(shù)據(jù)不是以前綴或任何縮進開頭,以便更容易嵌入其他格式化的JSON數(shù)據(jù)中。盡管src開頭的空格字符(空格,制表符,回車符,換行符)被刪除,但src末尾的空格符被保留并復制到dst。例如,如果src沒有尾隨空格,則dst; 如果src以結尾的換行符結束,那么dst。
package mainimport ("bytes""encoding/json""log""os")func main() { type Road struct { Name string Number int} roads := []Road{{"Diamond Fork", 29},{"Sheep Creek", 51},} b, err := json.Marshal(roads)if err != nil { log.Fatal(err)}var out bytes.Buffer json.Indent(&out, b, "=", "\t") out.WriteTo(os.Stdout)}
func Marshal(v interface{}) ([]byte, error)
Marshal返回v的JSON編碼。
marshal遞歸地遍歷值v。如果遇到的值實現(xiàn)了Marshaler接口并且不是零指針,則Marshal會調(diào)用其MarshalJSON方法生成JSON。如果沒有MarshalJSON方法存在,但該值實現(xiàn)的是encoding.TextMarshaler,Marshal會調(diào)用它的MarshalText方法并將結果編碼為JSON字符串。nil指針異常并不是絕對必要的,但它模仿了UnmarshalJSON行為中類似的必要異常。
否則,Marshal將使用以下依賴于類型的默認編碼:
布爾值編碼為JSON布爾值。
浮點數(shù),整數(shù)和數(shù)字值編碼為JSON數(shù)字。
字符串值被編碼為強制為有效UTF-8的JSON字符串,用Unicode替換符號替換無效字節(jié)。尖括號“<”和“>”會轉(zhuǎn)義為“\u003c”和“\u003e”,以防止某些瀏覽器將JSON輸出誤解為HTML。出于同樣的原因,&符號“&”也會轉(zhuǎn)義為“\ u0026”。這個轉(zhuǎn)義可以通過使用一個具有SetEscapeHTML(false)的編碼器來禁用。
數(shù)組和切片值的編碼方式為JSON數(shù)組,不同之處在于[]字節(jié)編碼為base64編碼的字符串,而無切片編碼為空JSON值。
結構值編碼為JSON對象。除非由于下面給出的原因之一而忽略該字段,否則每個導出的結構字段都將成為對象的成員,并使用字段名稱作為對象鍵。
每個結構字段的編碼可以通過結構字段標簽中“json”鍵下存儲的格式字符串來定制。格式字符串給出字段的名稱,可能后跟逗號分隔的選項列表。名稱可能為空,以指定選項而不覆蓋默認字段名稱。
“omitempty”選項指定如果字段具有空值,定義為false,0,零指針,nil接口值以及任何空數(shù)組,切片,映射或字符串,則該字段應從編碼中省略。
作為特殊情況,如果字段標簽是“ - ”,則該字段總是被省略。請注意,名稱為“ - ”的字段仍然可以使用標簽“ - ,”生成。
結構域標簽及其含義的示例:
// Field appears in JSON as key "myName".Field int `json:"myName"`// Field appears in JSON as key "myName" and// the field is omitted from the object if its value is empty,// as defined above.Field int `json:"myName,omitempty"`// Field appears in JSON as key "Field" (the default), but// the field is skipped if empty.// Note the leading comma.Field int `json:",omitempty"`// Field is ignored by this package.Field int `json:"-"`// Field appears in JSON as key "-".Field int `json:"-,"`
“string”選項表示字段在JSON編碼的字符串內(nèi)以JSON形式存儲。它僅適用于字符串,浮點,整數(shù)或布爾類型的字段。與JavaScript程序通信時,有時會使用這種額外的編碼級別:
Int64String int64 `json:",string"`
如果密鑰名稱是非空字符串,只包含Unicode引號,數(shù)字和ASCII標點符號(引號,反斜杠和逗號除外),則使用該名稱。
匿名結構字段通常會封送,就好像它們的內(nèi)部導出字段是外部結構中的字段一樣,受限于通常的Go可見性規(guī)則,如下一段所述。具有在其JSON標簽中給出的名稱的匿名結構字段被視為具有該名稱,而不是匿名的。接口類型的匿名結構字段被視為具有該類型作為它的名稱,而不是匿名。
在決定將哪個字段編組或解組時,修改JSON的結構字段的Go可見性規(guī)則。如果在同一級別有多個字段,并且該級別嵌套最少(因此將成為通常的Go規(guī)則選擇的嵌套級別),則適用以下額外規(guī)則:
1)在這些字段中,如果有任何字段是JSON標記的,則僅考慮標記字段,即使存在多個否則會發(fā)生沖突的未標記字段。
2)如果只有一個字段(根據(jù)第一條規(guī)則標記或不標記),則選擇該字段。
3)否則有多個字段,全部被忽略; 沒有錯誤發(fā)生。
處理匿名結構字段在Go 1.1中是新的。在Go 1.1之前,匿名結構字段被忽略。要強制忽略當前版本和早期版本中的匿名結構字段,請為該字段指定一個“ - ”的JSON標記。
地圖值編碼為JSON對象。該映射的鍵類型必須是一個字符串,一個整數(shù)類型或?qū)崿F(xiàn)encoding.TextMarshaler。通過應用以下規(guī)則,映射鍵被排序并用作JSON對象鍵,這些規(guī)則受上述字符串值描述的UTF-8強制的約束:
- string keys are used directly- encoding.TextMarshalers are marshaled- integer keys are converted to strings
指針值按照指向的值進行編碼。零指針編碼為空JSON值。
接口值編碼為接口中包含的值。一個無接口值編碼為空JSON值。
通道,complex和函數(shù)值不能用JSON編碼。嘗試對這種值進行編碼會導致Marshal返回一個UnsupportedTypeError。
JSON不能表示循環(huán)數(shù)據(jù)結構,而Marshal不處理它們。將循環(huán)結構傳遞給Marshal將導致無限遞歸。
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)}
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
MarshalIndent與Marshal類似,但應用縮進來格式化輸出。
func Unmarshal(data []byte, v interface{}) error
Unmarshal解析JSON編碼數(shù)據(jù)并將結果存儲在v指向的值中。如果v是零或不是指針,Unmarshal將返回一個InvalidUnmarshalError。
Unmarshal使用Marshal使用的編碼的逆矩陣,根據(jù)需要分配地圖,切片和指針,并使用以下附加規(guī)則:
要將JSON解組為一個指針,Unmarshal首先處理JSON為JSON literal的情況。在這種情況下,Unmarshal將指針設置為nil。否則,Unmarshal會將JSON解組為指針指向的值。如果指針為零,Unmarshal會為它指定一個新值。
要將JSON解組為一個實現(xiàn)Unmarshaler接口的值,Unmarshal調(diào)用該值的UnmarshalJSON方法,包括輸入為JSON null時的情況。否則,如果值實現(xiàn)了encoding.TextUnmarshaler并且輸入是JSON帶引號的字符串,則Unmarshal會使用該字符串的不帶引號的形式調(diào)用該值的UnmarshalText方法。
要將JSON解組到一個結構中,Unmarshal會將傳入的對象鍵與Marshal所使用的鍵(結構字段名稱或其標記)進行匹配,而不是匹配完全匹配,但也會接受不區(qū)分大小寫的匹配。Unmarshal只會設置結構的導出字段。
要將JSON解組為接口值,Unmarshal將其中一個存儲在接口值中:
bool, for JSON booleans float64, for JSON numbers string, for JSON strings[]interface{}, for JSON arrays map[string]interface{}, for JSON objects nil for JSON null
要將JSON數(shù)組解封片,Unmarshal將片長度重置為零,然后將每個元素追加到片中。作為一種特殊情況,為了將空JSON數(shù)組解組成一個片,Unmarshal用一個新的空片替換該片。
為了將JSON數(shù)組解組為一個Go數(shù)組,Unmarshal將JSON數(shù)組元素解碼為相應的Go數(shù)組元素。如果Go數(shù)組小于JSON數(shù)組,則會放棄其他JSON數(shù)組元素。如果JSON數(shù)組小于Go數(shù)組,則額外的Go數(shù)組元素將設置為零值。
為了將JSON對象解組映射到地圖,Unmarshal首先建立一個要使用的地圖。如果地圖為零,Unmarshal會分配一個新地圖。否則Unmarshal將重新使用現(xiàn)有的地圖,保留現(xiàn)有的條目。Unmarshal然后將來自JSON對象的鍵值對存儲到地圖中。映射的鍵類型必須是一個字符串,一個整數(shù),或?qū)崿F(xiàn)encoding.TextUnmarshaler。
如果JSON值不適合給定的目標類型,或者JSON數(shù)字溢出目標類型,則Unmarshal會跳過該字段并盡可能完成解組。如果沒有遇到更嚴重的錯誤,Unmarshal將返回一個描述最早此類錯誤的UnmarshalTypeError。在任何情況下,都不能保證有問題的后面的所有剩余字段將被解組到目標對象中。
通過將Go值設置為nil,JSON null值解組成接口,映射,指針或片。因為JSON中常常使用null來表示“不存在”,所以將JSON null解組為任何其他Go類型對該值沒有影響,并且不會產(chǎn)生錯誤。
解組引用的字符串時,無效的UTF-8或無效的UTF-16代理對不會被視為錯誤。相反,它們被替換為Unicode替換字符U + FFFD。
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)}
func Valid(data []byte) bool
有效報告數(shù)據(jù)是否是有效的JSON編碼。
解碼器從輸入流中讀取和解碼JSON值。
type Decoder struct { // contains filtered or unexported fields}
本示例使用Decoder來解碼不同JSON值的流。
package mainimport ("encoding/json""fmt""io""log""strings")func main() {const jsonStream = ` {"Name": "Ed", "Text": "Knock knock."} {"Name": "Sam", "Text": "Who's there?"} {"Name": "Ed", "Text": "Go fmt."} {"Name": "Sam", "Text": "Go fmt who?"} {"Name": "Ed", "Text": "Go fmt yourself!"} ` type Message struct { Name, Text string} dec := json.NewDecoder(strings.NewReader(jsonStream))for {var m Messageif err := dec.Decode(&m); err == io.EOF {break} else if err != nil { log.Fatal(err)} fmt.Printf("%s: %s\n", m.Name, m.Text)}}
func NewDecoder(r io.Reader) *Decoder
NewDecoder返回從r讀取的新解碼器。
解碼器引入了自己的緩沖區(qū),并且可以讀取超出請求的JSON值的r數(shù)據(jù)。
func (dec *Decoder) Buffered() io.Reader
緩沖返回解碼器緩沖區(qū)中剩余數(shù)據(jù)的閱讀器。直到下一次調(diào)用Decode,讀卡器才有效。
func (dec *Decoder) Decode(v interface{}) error
解碼從其輸入讀取下一個JSON編碼的值,并將其存儲在v指向的值中。
有關將JSON轉(zhuǎn)換為Go值的詳細信息,請參閱Unmarshal的文檔。
本示例使用Decoder解碼JSON對象的流數(shù)組。
package mainimport ("encoding/json""fmt""log""strings")func main() {const jsonStream = ` [ {"Name": "Ed", "Text": "Knock knock."}, {"Name": "Sam", "Text": "Who's there?"}, {"Name": "Ed", "Text": "Go fmt."}, {"Name": "Sam", "Text": "Go fmt who?"}, {"Name": "Ed", "Text": "Go fmt yourself!"} ] ` type Message struct { Name, Text string} dec := json.NewDecoder(strings.NewReader(jsonStream))// read open bracket t, err := dec.Token()if err != nil { log.Fatal(err)} fmt.Printf("%T: %v\n", t, t)// while the array contains valuesfor dec.More() {var m Message// decode an array value (Message) err := dec.Decode(&m)if err != nil { log.Fatal(err)} fmt.Printf("%v: %v\n", m.Name, m.Text)}// read closing bracket t, err = dec.Token()if err != nil { log.Fatal(err)} fmt.Printf("%T: %v\n", t, t)}
func (dec *Decoder) More() bool
更多報告當前數(shù)組或?qū)ο笫欠裼辛硪粋€元素被解析。
func (dec *Decoder) Token() (Token, error)
令牌返回輸入流中的下一個JSON令牌。在輸入流結束時,令牌返回nil,io.EOF。
令牌保證它返回的分隔符正確嵌套和匹配:如果令牌在輸入中遇到意外的分隔符,它將返回一個錯誤。
輸入流包含基本的JSON值(bool,string,number和null)以及Delim類型的分隔符{},以標記數(shù)組和對象的開始和結束。逗號和冒號被忽略。
本示例使用Decoder來解碼不同JSON值的流。
package mainimport ("encoding/json""fmt""io""log""strings")func main() {const jsonStream = ` {"Message": "Hello", "Array": [1, 2, 3], "Null": null, "Number": 1.234} ` dec := json.NewDecoder(strings.NewReader(jsonStream))for { t, err := dec.Token()if err == io.EOF {break}if err != nil { log.Fatal(err)} fmt.Printf("%T: %v", t, t)if dec.More() { fmt.Printf(" (more)")} fmt.Printf("\n")}}
func (dec *Decoder) UseNumber()
UseNumber使解碼器將數(shù)字解組為一個數(shù)字,而不是一個數(shù)字,而是一個數(shù)字,而不是一個float64。
Delim是JSON數(shù)組或?qū)ο蠓指舴?,即{或}之一。
type Delim rune
func (d Delim) String() string
編碼器將JSON值寫入輸出流。
type Encoder struct { // contains filtered or unexported fields}
func NewEncoder(w io.Writer) *Encoder
NewEncoder返回一個寫入w的新編碼器。
func (enc *Encoder) Encode(v interface{}) error
編碼將v的JSON編碼寫入流中,后跟一個換行符。
有關將Go值轉(zhuǎn)換為JSON的詳細信息,請參閱Marshal的文檔。
func (enc *Encoder) SetEscapeHTML(on bool)
SetEscapeHTML指定是否應在JSON引用字符串內(nèi)轉(zhuǎn)義有問題的HTML字符。默認行為是將&,<和>轉(zhuǎn)義為\ u0026,\ u003c和\ u003e,以避免將JSON嵌入到HTML中時可能出現(xiàn)的某些安全問題。
在非HTML設置中,轉(zhuǎn)義會干擾輸出的可讀性,SetEscapeHTML(false)會禁用此行為。
func (enc *Encoder) SetIndent(prefix, indent string)
SetIndent指示編碼器對每個后續(xù)編碼值進行格式化,就像由包級函數(shù)Indent(dst,src,prefix,indent)縮進一樣。調(diào)用SetIndent(“”,“”)將禁用縮進。
在Go 1.2之前,Marshal在嘗試使用無效的UTF-8序列對字符串值進行編碼時返回了InvalidUTF8Error。從Go 1.2開始,Marshal會將字符串替換為有效的UTF-8,方法是用Unicode替換符號U + FFFD替換無效字節(jié)。這個錯誤不再生成,而是為了向后兼容可能提及它的程序而保留。
type InvalidUTF8Error struct { S string // the whole string value that caused the error}
func (e *InvalidUTF8Error) Error() string
InvalidUnmarshalError描述傳遞給Unmarshal的無效參數(shù)。(Unmarshal的參數(shù)必須是非零指針。)
type InvalidUnmarshalError struct { Type reflect.Type}
func (e *InvalidUnmarshalError) Error() string
Marshaler是由可以將自己編組為有效JSON的類型實現(xiàn)的接口。
type Marshaler interface { MarshalJSON() ([]byte, error)}
type MarshalerError struct { Type reflect.Type Err error}
func (e *MarshalerError) Error() string
A Number represents a JSON number literal.
type Number string
func (n Number) Float64() (float64, error)
Float64將該數(shù)字作為float64返回。
func (n Number) Int64() (int64, error)
Int64將該數(shù)字作為int64返回。
func (n Number) String() string
字符串返回數(shù)字的文本文本。
RawMessage是一個原始編碼的JSON值。它實現(xiàn)了Marshaler和Unmarshaler,可用于延遲JSON解碼或預先計算JSON編碼。
type RawMessage []byte
這個例子使用RawMessage在編組期間使用預先計算的JSON。
package mainimport ("encoding/json""fmt""os")func main() { h := json.RawMessage(`{"precomputed": true}`) c := struct { Header *json.RawMessage `json:"header"` Body string `json:"body"`}{Header: &h, Body: "Hello Gophers!"} b, err := json.MarshalIndent(&c, "", "\t")if err != nil { fmt.Println("error:", err)} os.Stdout.Write(b)}
本示例使用RawMessage延遲解析JSON消息的一部分。
package mainimport ("encoding/json""fmt""log")func main() { type Color struct { Space string Point json.RawMessage // delay parsing until we know the color space} type RGB struct { R uint8 G uint8 B uint8} type YCbCr struct { Y uint8 Cb int8 Cr int8}var j = []byte(`[ {"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}, {"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255}} ]`)var colors []Color err := json.Unmarshal(j, &colors)if err != nil { log.Fatalln("error:", err)}for _, c := range colors {var dst interface{}switch c.Space {case "RGB": dst = new(RGB)case "YCbCr": dst = new(YCbCr)} err := json.Unmarshal(c.Point, dst)if err != nil { log.Fatalln("error:", err)} fmt.Println(c.Space, dst)}}
func (m RawMessage) MarshalJSON() ([]byte, error)
MarshalJSON返回m作為m的JSON編碼。
func (m *RawMessage) UnmarshalJSON(data []byte) error
UnmarshalJSON將* m設置為數(shù)據(jù)副本。
SyntaxError是對JSON語法錯誤的描述。
type SyntaxError struct { Offset int64 // error occurred after reading Offset bytes // contains filtered or unexported fields}
func (e *SyntaxError) Error() string
令牌具有以下其中一種類型的值:
Delim, for the four JSON delimiters [ ] { }bool, for JSON booleans float64, for JSON numbers Number, for JSON numbers string, for JSON string literals nil, for JSON null
type Token interface{}
UnmarshalFieldError描述了導致未導出(因此不可寫)結構字段的JSON對象鍵。(不再使用;保持兼容性。)
type UnmarshalFieldError struct { Key string Type reflect.Type Field reflect.StructField}
func (e *UnmarshalFieldError) Error() string
UnmarshalTypeError描述的JSON值不適合特定Go類型的值。
type UnmarshalTypeError struct { Value string // description of JSON value - "bool", "array", "number -5" Type reflect.Type // type of Go value it could not be assigned to Offset int64 // error occurred after reading Offset bytes Struct string // name of the struct type containing the field Field string // name of the field holding the Go value}
func (e *UnmarshalTypeError) Error() string
Unmarshaler是由可以解組自己的JSON描述的類型實現(xiàn)的接口。輸入可以被假定為JSON值的有效編碼。如果它希望在返回后保留數(shù)據(jù),則UnmarshalJSON必須復制JSON數(shù)據(jù)。
按照慣例,為了近似Unmarshal本身的行為,Unmarshalers實現(xiàn)UnmarshalJSON([] byte(“null”))作為no-op。
type Unmarshaler interface { UnmarshalJSON([]byte) error}
Marshal在嘗試對不支持的值類型進行編碼時返回UnsupportedTypeError。
type UnsupportedTypeError struct { Type reflect.Type}
func (e *UnsupportedTypeError) Error() string
type UnsupportedValueError struct { Value reflect.Value Str string}
func (e *UnsupportedValueError) Error() string