Go:什么时候json.Unmarshal结构返回错误?

时间:2015-09-22 05:01:57

标签: json go struct

假设我有一个像

这样的结构
type A struct{
  name string`json:"name"`
}

然后在主要我有代码

var jsonString string = `{"status":false}`
var a A
error := json.Unmarshal([]byte(jsonString),&a)

显然上面的代码产生了nil错误,无论json格式是否不同。什么时候json.Unmarshal()会在Go中返回错误?

3 个答案:

答案 0 :(得分:16)

如果源中的值与目标中的值不对应,则JSON解码器不会报告错误。例如,如果源包含字段“status”,则不是错误,但目标不包含。

Unmarshal函数确实在其他情况下返回错误:

语法错误

type A struct {
    Name string `json:"name"`
}
data = []byte(`{"name":what?}`)
err = json.Unmarshal(data, &a)
fmt.Println(err)  // prints character 'w' looking for beginning of value

类型不匹配

data := []byte(`{"name":false}`)
type B struct {
  Name string `json:"name"`
}
var b B
err = json.Unmarshal(data, &b)
fmt.Println(err) // prints cannot unmarshal bool into Go value of type string

playground example

答案 1 :(得分:7)

json.Unmarshal()返回错误时的更多示例(除了指定无效的JSON之外):

指定nilempty切片:

i := 0
err := json.Unmarshal(nil, &i)
fmt.Println(err) // unexpected end of JSON input

指定解组为unmarshal的非指针:

err = json.Unmarshal([]byte(`{"name":"a"}`), i)
fmt.Println(err) // json: Unmarshal(non-pointer int)

指定nil作为目标指针:

err = json.Unmarshal([]byte(`{"name":"a"}`), nil)
fmt.Println(err) // json: Unmarshal(nil)

指定会溢出目标类型的JSON号。引用json.Unmarshal()的文档:

  

如果JSON值不适合给定的目标类型,或者如果JSON编号溢出目标类型,则Unmarshal会跳过该字段并尽可能完成解组。如果没有遇到更严重的错误,Unmarshal将返回描述最早此类错误的UnmarshalTypeError。

为了证明这一点:

var j int8
err = json.Unmarshal([]byte(`1112`), &j)
fmt.Println(err) // json: cannot unmarshal number 1112 into Go value of type int8

或者在尝试解析某个不是RFC3339时间戳的time.Time时:

var t time.Time
err = json.Unmarshal([]byte(`"xx"`), &t)
fmt.Println(err) // parsing time ""xx"" as ""2006-01-02T15:04:05Z07:00"": cannot parse "xx"" as "2006"

答案 2 :(得分:2)

要添加到icza的答案,如果您尝试解组为键入的nil指针,也会出现错误。例如,如果你创建一个指向特定类型的指针,然后尝试解组到这些指针中的特定指针,就会发生这种情况。

package main

import (
    "fmt"
    "encoding/json"
)

type Example struct {Name string}


func main() {
        exs := make([]*Example, 5)
        err := json.Unmarshal([]byte(`{"name":"jane"}`), exs[0])
        fmt.Println(err)
}
// json: Unmarshal(nil *main.Example)