英文:
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 "API version"
}
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("Json:",string(data))
err = json.Unmarshal(data,&ver)
log.Println("Unmarshalled:",ver);
}
The output is:
2014/01/06 16:47:38 Json: {"API version":"1.2.3"}
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:"API version"`
}
This is done so that the json struct tags can co-exist with tags from other libraries (such as the XML encoder).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论