golang 定义嵌套结构类型

现在需要用 go 对接一个接口,接口的响应数据如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"success": true,
"data": {
"name": "hugo"
},
"identifi": {
"key": "xxx",
"secret": "secret"
},
"errors": [
{
"code": "not_found",
"message": "something"
}
]
}

我们可能会写如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Resp struct {
Success bool
Identifi RespIdentifi
Data interface{}
Errors []RespErr
}

type RespIdentifi struct {
Key string
Secret string
}
type RespError struct {
Code string
Message string
}

resp := new(Resp)
json.Unmarshal(respBody, resp)

可读性太差了,不能一眼看出来我们要解析的数据结构是怎样的,如果再稍微复杂一点的结构我们要一行一行的定义很多 type,而且很多时候我们只是需要读到响应的内容,不需要给这些嵌套的结构定义方法来操作它们。

好在 golang 是支持这样写的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Resp struct {
Success bool
Identifi struct {
Key string
Secret string
}
Data interface{}
Errors []struct {
Code string
Message string
}
}

resp := new(Resp)
json.Unmarshal(respBody, resp)

我在 Stackoverflow 上找到对这种写法的称呼叫 Unnamed struct,不过如果你要显示的去给这个类型的对象赋值就很头疼了,你需要将前面的未命名类型再声名一次:

1
2
3
4
5
6
7
8
9
10
11
resp := Resp{
Success: true,
Identify: struct {
Key string
Secret string
}{
Key: "xxx",
Secret: "xxx",
},
// ....
}

不过也并不影响它在前面的 Unmarshal 场景中很实用,另外这里有一篇看着就很头大的扩展阅读:https://gocn.vip/article/501 讲了 Unamed type 的各种奇葩表现。