英文:
How to represent this complex data structure with Go structs?
问题
所以我决定再给Go一次机会,但是遇到了困难。大部分Go结构体的示例在文档中都非常简单,我发现了以下的JSON对象表示法,但不知道如何用Go结构体表示:
{
    id: 1,
    version: "1.0",
    method: "someString",
    params: [
        {
            clientid: "string",
            nickname: "string",
            level: "string"
        },
        [{
            value: "string",
            "function": "string"
        }]
    ]
}
作为经验丰富的Go开发者,你会如何表示这种有点奇怪的数据?如何初始化结果结构体中的嵌套元素?
英文:
So I decided to give Go another chance but got stuck. Most Go struct examples in documentation are very simple and I found the following JSON object notation that I don't know how to represent with Go structs:
{
    id: 1,
    version: "1.0",
    method: "someString",
    params: [
        {
            clientid: "string",
            nickname: "string",
            level: "string"
        },
        [{
            value: "string",
            "function": "string"
        }]
    ]
}
How would you, more experienced gophers, represent that somewhat strange data in Go? And how to initialize the nested elements of the resulting struct?
答案1
得分: 12
我会使用json.RawMessage切片来表示params属性,然后通过一个GetXXX方法将其隐藏起来,以便进行良好的解码。类似于以下方式:
type Outer struct {
    Id      int               `json:"id"`
    Version string            `json:"version"`
    Method  string            `json:"method"`
    Params  []json.RawMessage `json:"params"`
}
type Client struct {
    ClientId string `json:"clientid"`
    Nickname string `json:"nickname"`
    Level    string `json:"level"`
}
...
obj := Outer{}
err := json.Unmarshal([]byte(js), &obj)
if err != nil {
    fmt.Println(err)
}
fmt.Println(obj.Method) // 输出 "someString"
client := Client{}
err = json.Unmarshal(obj.Params[0], &client)
fmt.Println(client.Nickname) // 输出 "string"
这是一个快速拼凑的示例,第二个param需要你提供一些输入...但基本上你需要将其解码为一个表示该类型的切片。
英文:
I would use a json.RawMessage  slice for the params property.. then hide them behind an GetXXX method that decodes it all nicely. Somewhat like this:
type Outer struct {
	Id      int               `json:"id"`
	Version string            `json:"version"`
	Method  string            `json:"method"`
	Params  []json.RawMessage `json:"params"`
}
type Client struct {
	ClientId string `json:"clientid"`
	Nickname string `json:"nickname"`
	Level    string `json:"level"`
}
....
obj := Outer{}
err := json.Unmarshal([]byte(js), &obj)
if err != nil {
	fmt.Println(err)
}
fmt.Println(obj.Method) // prints "someString"
client := Client{}
err = json.Unmarshal(obj.Params[0], &client)
fmt.Println(client.Nickname) // prints "string"
Working (quickly smashed together at lunch time) sample: http://play.golang.org/p/Gp7UKj6pRK
That second param will need some input from you .. but you're basically looking at decoding it to a slice of whatever type you create to represent it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论