英文:
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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论