json.Unmarshal似乎不关注结构标签。

huangapple go评论81阅读模式
英文:

json.Unmarshal doesn't seem to pay attention to struct tags

问题

我有一个看起来像这样的 JSON 对象:

{"API version":"1.2.3"}

我想使用 Go 中的 json.Unmarshal() 函数将其转换为对象。根据这篇博客文章

Unmarshal 如何确定要存储解码数据的字段?对于给定的 JSON 键 "Foo"Unmarshal 将遍历目标结构体的字段以按照以下优先顺序查找:

  • 带有标签 "Foo" 的导出字段(有关结构体标签的更多信息,请参阅Go 规范),
  • 名为 "Foo" 的导出字段,或者
  • 名为 "FOO""FoO" 或其他不区分大小写的匹配项的导出字段。

这在 unmarshal 文档 中得到了确认。

由于 "API version" 中有一个空格,这不是一个有效的 Go 标识符,所以我在字段上使用了一个标签:

type ApiVersion struct {
    Api_version string "API version"
}

然后我尝试这样解组它:

func GetVersion() (ver ApiVersion, err error) {
    // 省略获取 JSON 的代码
    log.Println("Json:", string(data))
    err = json.Unmarshal(data, &ver)
    log.Println("Unmarshalled:", ver)
}

输出结果是:

2014/01/06 16:47:38 Json: {"API version":"1.2.3"}
2014/01/06 16:47:38 Unmarshalled: {}

如你所见,JSON 没有被解组到 ver 中。我漏掉了什么?

英文:

I have a JSON object that looks like this:

{"API version":"1.2.3"}

And I want to convert it to an object it using the json.Unmarshal() function in go. According to this blog post:

> How does Unmarshal identify the fields in which to store the decoded data? For a given JSON key "Foo", Unmarshal will look through the destination struct's fields to find (in order of preference):

> * An exported field with a tag of "Foo" (see the Go spec for more on struct tags),

  • An exported field named "Foo", or
  • An exported field named "FOO" or "FoO" or some other case-insensitive match of "Foo".

This is confirmed by the unmarshal documentation.

Since "API version" has a space in it, which is not a valid go identifier, I used a tag on the field:

<!-- language: lang-golang -->

type ApiVersion struct {
 Api_version string &quot;API version&quot;
}

And I try to unmarshal it like so:

<!-- language: lang-golang -->

func GetVersion() (ver ApiVersion, err error) {

 // Snip code that gets the JSON

 log.Println(&quot;Json:&quot;,string(data))
 err = json.Unmarshal(data,&amp;ver)
 log.Println(&quot;Unmarshalled:&quot;,ver);
}

The output is:

2014/01/06 16:47:38 Json: {&quot;API version&quot;:&quot;1.2.3&quot;}
2014/01/06 16:47:38 Unmarshalled: {}

As you can see, the JSON isn't being marshalled into ver. What am I missing?

答案1

得分: 3

encoding/json 模块要求结构标签进行命名空间处理。因此,你可能需要像这样修改:

type ApiVersion struct {
    Api_version string `json:"API version"`
}

这样做是为了让 json 结构标签能够与其他库(比如 XML 编码器)的标签共存。

英文:

The encoding/json module requires that the struct tags be namespaced. So you instead want something like:

type ApiVersion struct {
    Api_version string `json:&quot;API version&quot;`
}

This is done so that the json struct tags can co-exist with tags from other libraries (such as the XML encoder).

huangapple
  • 本文由 发表于 2014年1月6日 14:03:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/20943963.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定