【发布时间】:2014-09-25 08:39:39
【问题描述】:
我正在通过编写一个简单的 http 服务器来学习 Go,我需要处理一些 JSON 响应。
对于一个对象响应,我可以用 2 行代码习惯性地解组它: structResult := Foo{} json.Unmarshal(structBody, &structResult)
我不知道如何对数组响应做同样的事情(见下面的例子)。有没有办法指定(可能通过 json 标签)顶级数组应该进入给定的结构字段?
package main
import "fmt"
import "encoding/json"
type Foo struct {
Id uint64 `json:"id"`
Name string `json:"name"`
}
type BaseResult struct {
Error string `json:"error"`
}
type FooResult struct {
BaseResult
Foos []Foo
}
func main() {
// Simple and works.
structBody := []byte(`{"id": 1,"name": "foo"}`)
structResult := Foo{}
json.Unmarshal(structBody, &structResult)
fmt.Printf("%#v\n", structResult)
// Doesn't work.
arrayBody := []byte(`[{"id": 1,"name": "foo"},{"id": 2,"name": "bar"},{"id": 3,"name": "foobar"}]`)
arrayResult := FooResult{}
json.Unmarshal(arrayBody, &arrayResult)
fmt.Printf("%#v\n", arrayResult)
}
我知道我可以让 FooResult 成为一个数组:
type FooResult []Foo
但是我失去了指定我想用来存储错误消息等的基础对象的能力。我也知道我可以直接解组为 &fooResult.Foos,但我希望代码可以同时处理对象和数组。
更新
按照@dyoo 的建议实施 UnmarshalJSON 部分解决了我的问题,但我希望我可以使用 BaseResult 来存储解析错误,以防 JSON 具有不同的结构:
arrayBody := []byte(`{"error": "foo"}`)
arrayResult := FooResult{}
json.Unmarshal(arrayBody, &arrayResult)
fmt.Printf("%#v\n", arrayResult)
当然,我可以在 UnmarshalJSON 中实现更复杂的逻辑 - 但没有更简单的方法吗?
【问题讨论】:
-
建议:将
FooResult重命名为ArrayResult。使用Foo作为名称的任何部分通常是可疑的,因为它没有任何意义。 -
当然,我在这个例子中只使用了“foo”这个名字。