自定义的Go语言中的JSON映射函数

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

Custom JSON mapping function in Go

问题

所以我正在制作一个调用restful API的Go服务,我无法控制我所调用的API。

我知道Go有一个很好的内置反序列化器NewDecoder->Decode,但它只适用于以大写字母开头的结构字段(即公共字段)。这会带来一个问题,因为我要消费的JSON看起来像这样:

  1. {
  2. "_next": "someValue",
  3. "data": [{/*一组对象*/}],
  4. "message": "success"
  5. }

我该如何映射"_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:

  1. {
  2. "_next": "someValue",
  3. "data": [{/*a collection of objects*/}],
  4. "message": "success"
  5. }

How the heck would I map "_next"?

答案1

得分: 5

使用标签(tags)来指定JSON中的字段名。你上面发布的JSON对象可以像这样建模:

  1. type Something struct {
  2. Next string `json:"_next"`
  3. Data []interface{} `json:"data"`
  4. Message string `json:"message"`
  5. }

进行测试:

  1. func main() {
  2. var sg Something
  3. if err := json.Unmarshal([]byte(s), &sg); err != nil {
  4. panic(err)
  5. }
  6. fmt.Printf("%+v", sg)
  7. }

常量s的值为:

  1. const s = `{
  2. "_next": "someValue",
  3. "data": ["one", 2],
  4. "message": "success"
  5. }`

输出结果(在Go Playground上尝试):

  1. {Next:someValue Data:[one 2] Message:success}

还要注意,你也可以将JSON解组成map或interface{}值,这样你甚至不需要创建结构体,但是使用结构体会更方便:

  1. func main() {
  2. var m map[string]interface{}
  3. if err := json.Unmarshal([]byte(s), &m); err != nil {
  4. panic(err)
  5. }
  6. fmt.Printf("%+v", m)
  7. }

常量s的值为:

  1. const s = `{
  2. "_next": "someValue",
  3. "data": ["one", 2],
  4. "message": "success"
  5. }`

输出结果(在Go Playground上尝试):

  1. map[_next:someValue data:[one 2] message:success]
  1. 只返回翻译好的部分,不要有别的内容。
  2. <details>
  3. <summary>英文:</summary>
  4. Use [tags][1] to specify the field name in JSON. The JSON object you posted above can be modeled like this:
  5. type Something struct {
  6. Next string `json:&quot;_next&quot;`
  7. Data []interface{} `json:&quot;data&quot;`
  8. Message string `json:&quot;message&quot;`
  9. }
  10. Testing it:
  11. func main() {
  12. var sg Something
  13. if err := json.Unmarshal([]byte(s), &amp;sg); err != nil {
  14. panic(err)
  15. }
  16. fmt.Printf(&quot;%+v&quot;, sg)
  17. }
  18. const s = `{
  19. &quot;_next&quot;: &quot;someValue&quot;,
  20. &quot;data&quot;: [&quot;one&quot;, 2],
  21. &quot;message&quot;: &quot;success&quot;
  22. }`
  23. Output (try it on the [Go Playground][2]):
  24. {Next:someValue Data:[one 2] Message:success}
  25. Also note that you may also unmarshal into maps or `interface{}` values, so you don&#39;t even have to create structs, but it won&#39;t be as convenient using it as the structs:
  26. func main() {
  27. var m map[string]interface{}
  28. if err := json.Unmarshal([]byte(s), &amp;m); err != nil {
  29. panic(err)
  30. }
  31. fmt.Printf(&quot;%+v&quot;, m)
  32. }
  33. const s = `{
  34. &quot;_next&quot;: &quot;someValue&quot;,
  35. &quot;data&quot;: [&quot;one&quot;, 2],
  36. &quot;message&quot;: &quot;success&quot;
  37. }`
  38. Output (try it on the [Go Playground][3]):
  39. map[_next:someValue data:[one 2] message:success]
  40. [1]: https://stackoverflow.com/questions/10858787/what-are-the-uses-for-tags-in-go/30889373#30889373
  41. [2]: https://play.golang.org/p/NJCkBpzdfn
  42. [3]: https://play.golang.org/p/cuKkKmlp5a
  43. </details>
  44. # 答案2
  45. **得分**: 0
  46. 标签将解决你的问题。
  47. 希望这对其他来到这里的人有所帮助,你可以使用https://mholt.github.io/json-to-go/来生成Go结构体。将JSON结构粘贴到左侧,相应的Go类型将生成在右侧,你可以将其粘贴到你的程序中。
  48. <details>
  49. <summary>英文:</summary>
  50. Tags will solve your problem.
  51. 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.
  52. </details>

huangapple
  • 本文由 发表于 2017年3月27日 23:16:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/43050246.html
匿名

发表评论

匿名网友

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

确定