假设我有一个像
这样的结构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中返回错误?
答案 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
答案 1 :(得分:7)
json.Unmarshal()
返回错误时的更多示例(除了指定无效的JSON之外):
指定nil
或empty
切片:
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)