为了账号安全,请及时绑定邮箱和手机立即绑定

Go : json.Unmarshal 什么时候会返回 struct 错误?

Go : json.Unmarshal 什么时候会返回 struct 错误?

Go
catspeake 2021-11-08 17:00:23
假设我有一个像type A struct{  name string`json:"name"`}然后在主要我有代码var jsonString string = `{"status":false}`var a Aerror := json.Unmarshal([]byte(jsonString),&a)显然上面的代码会产生一个 nil 错误,不管 json 格式是不同的。json.Unmarshal() 什么时候会在 Go 中返回错误?
查看完整描述

3 回答

?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

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


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

目标类型无法表示的 JSON 值:


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

(这是一个不能用目标类型表示值的例子。还有更多。)


查看完整回答
反对 回复 2021-11-08
?
手掌心

TA贡献1942条经验 获得超3个赞

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


指定一个nil或empty切片:


i := 0

err := json.Unmarshal(nil, &i)

fmt.Println(err) // unexpected end of JSON input

指定一个非指针解组为:


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

或者当尝试将某些内容解析time.Time为不是 RFC3339 时间戳的 a 时:


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"



查看完整回答
反对 回复 2021-11-08
?
绝地无双

TA贡献1946条经验 获得超4个赞

要添加到 icza 的答案中,如果您尝试将 Unmarshal 解组为类型化的 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)


查看完整回答
反对 回复 2021-11-08
  • 3 回答
  • 0 关注
  • 319 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信