©
本文档使用
php.cn手册 发布
import "encoding/json"
Overview
Index
Examples
包json实现了RFC 4627中定义的JSON的编码和解码。JSON和Go值之间的映射在Marshal和Unmarshal函数的文档中进行了描述。
有关此包的介绍,请参阅“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>标签内。由于历史原因,Web浏览器不遵守<script>标签内的标准HTML转义,因此必须使用替代的JSON编码。
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
缩进附加到JSON编码的src的缩进形式的dst。JSON对象或数组中的每个元素都以一个新的缩进行开始,该行以前缀开头,随后是根据缩进嵌套的一个或多个缩进副本。追加到dst的数据不是以前缀或任何缩进开头,以便更容易嵌入其他格式化的JSON数据中。尽管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。如果遇到的值实现了Marshaler接口并且不是零指针,则Marshal会调用其MarshalJSON方法生成JSON。如果没有MarshalJSON方法存在,但该值实现的是encoding.TextMarshaler,Marshal会调用它的MarshalText方法并将结果编码为JSON字符串。nil指针异常并不是绝对必要的,但它模仿了UnmarshalJSON行为中类似的必要异常。
否则,Marshal将使用以下依赖于类型的默认编码:
布尔值编码为JSON布尔值。
浮点数,整数和数字值编码为JSON数字。
字符串值被编码为强制为有效UTF-8的JSON字符串,用Unicode替换符号替换无效字节。尖括号“<”和“>”会转义为“\u003c”和“\u003e”,以防止某些浏览器将JSON输出误解为HTML。出于同样的原因,&符号“&”也会转义为“\ u0026”。这个转义可以通过使用一个具有SetEscapeHTML(false)的编码器来禁用。
数组和切片值的编码方式为JSON数组,不同之处在于[]字节编码为base64编码的字符串,而无切片编码为空JSON值。
结构值编码为JSON对象。除非由于下面给出的原因之一而忽略该字段,否则每个导出的结构字段都将成为对象的成员,并使用字段名称作为对象键。
每个结构字段的编码可以通过结构字段标签中“json”键下存储的格式字符串来定制。格式字符串给出字段的名称,可能后跟逗号分隔的选项列表。名称可能为空,以指定选项而不覆盖默认字段名称。
“omitempty”选项指定如果字段具有空值,定义为false,0,零指针,nil接口值以及任何空数组,切片,映射或字符串,则该字段应从编码中省略。
作为特殊情况,如果字段标签是“ - ”,则该字段总是被省略。请注意,名称为“ - ”的字段仍然可以使用标签“ - ,”生成。
结构域标签及其含义的示例:
// 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编码的字符串内以JSON形式存储。它仅适用于字符串,浮点,整数或布尔类型的字段。与JavaScript程序通信时,有时会使用这种额外的编码级别:
Int64String int64 `json:",string"`
如果密钥名称是非空字符串,只包含Unicode引号,数字和ASCII标点符号(引号,反斜杠和逗号除外),则使用该名称。
匿名结构字段通常会封送,就好像它们的内部导出字段是外部结构中的字段一样,受限于通常的Go可见性规则,如下一段所述。具有在其JSON标签中给出的名称的匿名结构字段被视为具有该名称,而不是匿名的。接口类型的匿名结构字段被视为具有该类型作为它的名称,而不是匿名。
在决定将哪个字段编组或解组时,修改JSON的结构字段的Go可见性规则。如果在同一级别有多个字段,并且该级别嵌套最少(因此将成为通常的Go规则选择的嵌套级别),则适用以下额外规则:
1)在这些字段中,如果有任何字段是JSON标记的,则仅考虑标记字段,即使存在多个否则会发生冲突的未标记字段。
2)如果只有一个字段(根据第一条规则标记或不标记),则选择该字段。
3)否则有多个字段,全部被忽略; 没有错误发生。
处理匿名结构字段在Go 1.1中是新的。在Go 1.1之前,匿名结构字段被忽略。要强制忽略当前版本和早期版本中的匿名结构字段,请为该字段指定一个“ - ”的JSON标记。
地图值编码为JSON对象。该映射的键类型必须是一个字符串,一个整数类型或实现encoding.TextMarshaler。通过应用以下规则,映射键被排序并用作JSON对象键,这些规则受上述字符串值描述的UTF-8强制的约束:
- string keys are used directly- encoding.TextMarshalers are marshaled- integer keys are converted to strings
指针值按照指向的值进行编码。零指针编码为空JSON值。
接口值编码为接口中包含的值。一个无接口值编码为空JSON值。
通道,complex和函数值不能用JSON编码。尝试对这种值进行编码会导致Marshal返回一个UnsupportedTypeError。
JSON不能表示循环数据结构,而Marshal不处理它们。将循环结构传递给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编码数据并将结果存储在v指向的值中。如果v是零或不是指针,Unmarshal将返回一个InvalidUnmarshalError。
Unmarshal使用Marshal使用的编码的逆矩阵,根据需要分配地图,切片和指针,并使用以下附加规则:
要将JSON解组为一个指针,Unmarshal首先处理JSON为JSON literal的情况。在这种情况下,Unmarshal将指针设置为nil。否则,Unmarshal会将JSON解组为指针指向的值。如果指针为零,Unmarshal会为它指定一个新值。
要将JSON解组为一个实现Unmarshaler接口的值,Unmarshal调用该值的UnmarshalJSON方法,包括输入为JSON null时的情况。否则,如果值实现了encoding.TextUnmarshaler并且输入是JSON带引号的字符串,则Unmarshal会使用该字符串的不带引号的形式调用该值的UnmarshalText方法。
要将JSON解组到一个结构中,Unmarshal会将传入的对象键与Marshal所使用的键(结构字段名称或其标记)进行匹配,而不是匹配完全匹配,但也会接受不区分大小写的匹配。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数组解封片,Unmarshal将片长度重置为零,然后将每个元素追加到片中。作为一种特殊情况,为了将空JSON数组解组成一个片,Unmarshal用一个新的空片替换该片。
为了将JSON数组解组为一个Go数组,Unmarshal将JSON数组元素解码为相应的Go数组元素。如果Go数组小于JSON数组,则会放弃其他JSON数组元素。如果JSON数组小于Go数组,则额外的Go数组元素将设置为零值。
为了将JSON对象解组映射到地图,Unmarshal首先建立一个要使用的地图。如果地图为零,Unmarshal会分配一个新地图。否则Unmarshal将重新使用现有的地图,保留现有的条目。Unmarshal然后将来自JSON对象的键值对存储到地图中。映射的键类型必须是一个字符串,一个整数,或实现encoding.TextUnmarshaler。
如果JSON值不适合给定的目标类型,或者JSON数字溢出目标类型,则Unmarshal会跳过该字段并尽可能完成解组。如果没有遇到更严重的错误,Unmarshal将返回一个描述最早此类错误的UnmarshalTypeError。在任何情况下,都不能保证有问题的后面的所有剩余字段将被解组到目标对象中。
通过将Go值设置为nil,JSON null值解组成接口,映射,指针或片。因为JSON中常常使用null来表示“不存在”,所以将JSON null解组为任何其他Go类型对该值没有影响,并且不会产生错误。
解组引用的字符串时,无效的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
有效报告数据是否是有效的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读取的新解码器。
解码器引入了自己的缓冲区,并且可以读取超出请求的JSON值的r数据。
func (dec *Decoder) Buffered() io.Reader
缓冲返回解码器缓冲区中剩余数据的阅读器。直到下一次调用Decode,读卡器才有效。
func (dec *Decoder) Decode(v interface{}) error
解码从其输入读取下一个JSON编码的值,并将其存储在v指向的值中。
有关将JSON转换为Go值的详细信息,请参阅Unmarshal的文档。
本示例使用Decoder解码JSON对象的流数组。
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
更多报告当前数组或对象是否有另一个元素被解析。
func (dec *Decoder) Token() (Token, error)
令牌返回输入流中的下一个JSON令牌。在输入流结束时,令牌返回nil,io.EOF。
令牌保证它返回的分隔符正确嵌套和匹配:如果令牌在输入中遇到意外的分隔符,它将返回一个错误。
输入流包含基本的JSON值(bool,string,number和null)以及Delim类型的分隔符{},以标记数组和对象的开始和结束。逗号和冒号被忽略。
本示例使用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使解码器将数字解组为一个数字,而不是一个数字,而是一个数字,而不是一个float64。
Delim是JSON数组或对象分隔符,即{或}之一。
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值转换为JSON的详细信息,请参阅Marshal的文档。
func (enc *Encoder) SetEscapeHTML(on bool)
SetEscapeHTML指定是否应在JSON引用字符串内转义有问题的HTML字符。默认行为是将&,<和>转义为\ u0026,\ u003c和\ u003e,以避免将JSON嵌入到HTML中时可能出现的某些安全问题。
在非HTML设置中,转义会干扰输出的可读性,SetEscapeHTML(false)会禁用此行为。
func (enc *Encoder) SetIndent(prefix, indent string)
SetIndent指示编码器对每个后续编码值进行格式化,就像由包级函数Indent(dst,src,prefix,indent)缩进一样。调用SetIndent(“”,“”)将禁用缩进。
在Go 1.2之前,Marshal在尝试使用无效的UTF-8序列对字符串值进行编码时返回了InvalidUTF8Error。从Go 1.2开始,Marshal会将字符串替换为有效的UTF-8,方法是用Unicode替换符号U + FFFD替换无效字节。这个错误不再生成,而是为了向后兼容可能提及它的程序而保留。
type InvalidUTF8Error struct { S string // the whole string value that caused the error}
func (e *InvalidUTF8Error) Error() string
InvalidUnmarshalError描述传递给Unmarshal的无效参数。(Unmarshal的参数必须是非零指针。)
type InvalidUnmarshalError struct { Type reflect.Type}
func (e *InvalidUnmarshalError) Error() string
Marshaler是由可以将自己编组为有效JSON的类型实现的接口。
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将该数字作为float64返回。
func (n Number) Int64() (int64, error)
Int64将该数字作为int64返回。
func (n Number) String() string
字符串返回数字的文本文本。
RawMessage是一个原始编码的JSON值。它实现了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设置为数据副本。
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描述的类型实现的接口。输入可以被假定为JSON值的有效编码。如果它希望在返回后保留数据,则UnmarshalJSON必须复制JSON数据。
按照惯例,为了近似Unmarshal本身的行为,Unmarshalers实现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