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

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

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:&quot;_next&quot;`
    	Data    []interface{} `json:&quot;data&quot;`
    	Message string        `json:&quot;message&quot;`
    }

Testing it:

    func main() {
    	var sg Something
    	if err := json.Unmarshal([]byte(s), &amp;sg); err != nil {
    		panic(err)
    	}
    	fmt.Printf(&quot;%+v&quot;, sg)
    }
    
    const s = `{
        &quot;_next&quot;: &quot;someValue&quot;,
        &quot;data&quot;:  [&quot;one&quot;, 2],
        &quot;message&quot;: &quot;success&quot;
    }`

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&#39;t even have to create structs, but it won&#39;t be as convenient using it as the structs:

    func main() {
    	var m map[string]interface{}
    	if err := json.Unmarshal([]byte(s), &amp;m); err != nil {
    		panic(err)
    	}
    	fmt.Printf(&quot;%+v&quot;, m)
    }
    
    const s = `{
        &quot;_next&quot;: &quot;someValue&quot;,
        &quot;data&quot;:  [&quot;one&quot;, 2],
        &quot;message&quot;: &quot;success&quot;
    }`

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>



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:

确定