JSON解码器无法将对象解码为对象

Posted

技术标签:

【中文标题】JSON解码器无法将对象解码为对象【英文标题】:JSON Decoder cannot decode an object into an object 【发布时间】:2022-01-07 21:10:08 【问题描述】:
type MiddleMan struct 
    User CompletedByUser `json:"user"`

type CompletedByUser struct 
    DisplayName string `json:"displayName"`
    Id          string `json:"id"`

使用以下类型,我运行代码

shorterJsonString := `
    "user":
        "displayName":null,
        "id":"a03dfee5-a754-4eb9"
    
 `

if !json.Valid([]byte(shorterJsonString)) 
    log.Println("Not valid")

var middleMan models.MiddleMan

newReader := strings.NewReader(shorterJsonString)
json.NewDecoder(newReader).Decode(&middleMan)

log.Println(middleMan)

不幸的是,嵌套对象的解码器似乎被破坏了。打印出来的不是实际的物体,而是打印出来

 a03dfee5-a754-4eb9 

它似乎将整个事物展平到 id 字段中。这是怎么回事?

【问题讨论】:

您正在打印的 middleMan 的类型为 models.MiddleMan。它与 JSON 无关,因此将接收来自log.Println 的 fmt 样式格式,它喜欢省略字段名称以及空字段。您可以使用log.Printf("%+v\n", middleMan) 让它稍微冗长一些。你想完成什么? 【参考方案1】:

您预计会发生什么/被打印出来?

log 包(使用fmt 包)打印用大括号括起来的结构,列出用空格分隔的字段值。

您的MiddleMan 有一个字段,所以它看起来像这样:

field

其中field 是另一个struct 类型为CompletedByUser,它有2 个字段,所以它看起来像这样:

field1 field2

其中fieldstring 类型,为空字符串,因此您会看到field2 的值以空格为前缀:

 a03dfee5-a754-4eb9

如果你打印它添加字段名称:

log.Printf("%+v", middleMan)

你会看到如下输出:

User:DisplayName: Id:a03dfee5-a754-4eb9

使用另一种(Go 语法)格式:

log.Printf("%#v", middleMan)

输出:

main.MiddleManUser:main.CompletedByUserDisplayName:"", Id:"a03dfee5-a754-4eb9"

在Go Playground 上试试这个。

【讨论】:

我预计它会打印整个内容,并且不会意外地省略大部分对象。这在我看来是疯狂的行为。我希望一个简单的 Println("smth") 可以简单地打印“smth”,而不是像在大多数语言中那样根据自己的偏见对其进行过滤。

以上是关于JSON解码器无法将对象解码为对象的主要内容,如果未能解决你的问题,请参考以下文章

django rest api:JSON 解析错误 - 无法解码 JSON 对象

Swift 4 Decodable - 将 JSON 对象解码为“数据”

您可以将子 JSON 对象解码为其字符串表示形式而不是具体类型吗?

显示比“无法解码 JSON 对象”更好的错误消息

如何修复“JSONDecodeError:无法解码 JSON 对象:第 1 行第 0 列(字符 0)”?

kendoui parameterMap 解码 php 对象的正确 json 编码是啥?