英文:
Custom JSON mapping function in Go
问题
所以我正在制作一个调用restful API的Go服务,我无法控制我所调用的API。
我知道Go有一个很好的内置反序列化器NewDecoder->Decode,但它只适用于以大写字母开头的结构字段(即公共字段)。这会带来一个问题,因为我要消费的JSON看起来像这样:
{
"_next": "someValue",
"data": [{/*一组对象*/}],
"message": "success"
}
我该如何映射"_next"
这个字段?
英文:
So I'm making a Go service that makes a call to a restful API, I have no control over the API I'm calling.
I know that Go has a nice built in deserializer in NewDecoder->Decode, but it only works for struct fields that start with capital letters (aka public fields). Which poses a problem because the JSON I'm trying to consume looks like this:
{
"_next": "someValue",
"data": [{/*a collection of objects*/}],
"message": "success"
}
How the heck would I map "_next"
?
答案1
得分: 5
使用标签(tags)来指定JSON中的字段名。你上面发布的JSON对象可以像这样建模:
type Something struct {
Next string `json:"_next"`
Data []interface{} `json:"data"`
Message string `json:"message"`
}
进行测试:
func main() {
var sg Something
if err := json.Unmarshal([]byte(s), &sg); err != nil {
panic(err)
}
fmt.Printf("%+v", sg)
}
常量s的值为:
const s = `{
"_next": "someValue",
"data": ["one", 2],
"message": "success"
}`
输出结果(在Go Playground上尝试):
{Next:someValue Data:[one 2] Message:success}
还要注意,你也可以将JSON解组成map或interface{}
值,这样你甚至不需要创建结构体,但是使用结构体会更方便:
func main() {
var m map[string]interface{}
if err := json.Unmarshal([]byte(s), &m); err != nil {
panic(err)
}
fmt.Printf("%+v", m)
}
常量s的值为:
const s = `{
"_next": "someValue",
"data": ["one", 2],
"message": "success"
}`
输出结果(在Go Playground上尝试):
map[_next:someValue data:[one 2] message:success]
只返回翻译好的部分,不要有别的内容。
<details>
<summary>英文:</summary>
Use [tags][1] to specify the field name in JSON. The JSON object you posted above can be modeled like this:
type Something struct {
Next string `json:"_next"`
Data []interface{} `json:"data"`
Message string `json:"message"`
}
Testing it:
func main() {
var sg Something
if err := json.Unmarshal([]byte(s), &sg); err != nil {
panic(err)
}
fmt.Printf("%+v", sg)
}
const s = `{
"_next": "someValue",
"data": ["one", 2],
"message": "success"
}`
Output (try it on the [Go Playground][2]):
{Next:someValue Data:[one 2] Message:success}
Also note that you may also unmarshal into maps or `interface{}` values, so you don't even have to create structs, but it won't be as convenient using it as the structs:
func main() {
var m map[string]interface{}
if err := json.Unmarshal([]byte(s), &m); err != nil {
panic(err)
}
fmt.Printf("%+v", m)
}
const s = `{
"_next": "someValue",
"data": ["one", 2],
"message": "success"
}`
Output (try it on the [Go Playground][3]):
map[_next:someValue data:[one 2] message:success]
[1]: https://stackoverflow.com/questions/10858787/what-are-the-uses-for-tags-in-go/30889373#30889373
[2]: https://play.golang.org/p/NJCkBpzdfn
[3]: https://play.golang.org/p/cuKkKmlp5a
</details>
# 答案2
**得分**: 0
标签将解决你的问题。
希望这对其他来到这里的人有所帮助,你可以使用https://mholt.github.io/json-to-go/来生成Go结构体。将JSON结构粘贴到左侧,相应的Go类型将生成在右侧,你可以将其粘贴到你的程序中。
<details>
<summary>英文:</summary>
Tags will solve your problem.
Hoping it may help others who come here, you can make use of https://mholt.github.io/json-to-go/ to generate Go structs. Paste a JSON structure on the left and the equivalent Go type will be generated to the right, which you can paste into your program.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论