2 回答
TA贡献1797条经验 获得超6个赞
你会因为第一个错误而自责——你的 JSON 有,result但你的 struct 标签有response.
第二个问题比较棘手。问题是您声明您的Asset地图作为名为“资产”的键嵌套在结果中,但事实并非如此。其实它只是所有结果的按键其他比成功/错误。不幸的是,encoding/json没有任何方式来表达这一点。你可以说它result是 a map[string]interface{},然后成功/错误(如果它们存在)将是 bool/string,并且资产将更多map[string]interface{}s 包含所有其他字段的键。这是可行的,但它有点丑陋/效率低下,如果您想转换为适当的结构类型以便您可以在其上拥有方法,则需要做很多工作。
也许更好的方法是解码成这种类型:
type AssetIntermediate struct {
Result map[string]json.RawMessage `json:"result"`
}
以及拥有
type Asset struct { /* all those fields */ }
type AssetInfo struct {
Success bool
Error string
Assets map[string]Asset
}
然后你可以做
var intermediate AssetIntermediate
err := json.Unmarshal(data, &intermediate)
/* handle err */
var ai AssetInfo
/* At this point, intermediate.Result is a map
* of strings to json.RawMessage, which is just a []byte
* containing not-yet-decoded JSON. We want to take
* each field and put it into ai where it belongs.
*/
for k, v := range intermediate.Result {
var err error
// error and success keys are decoded into the respective fields
if k == "error" {
err = json.Unmarshal(v, &ai.Error)
} else if k == "success" {
err = json.Unmarshal(v, &ai.Success)
} else {
// Otherwise, we have an asset. First decode it...
var asset Asset
err = json.Unmarshal(v, &asset)
if err == nil {
// Create the Assets map if it doesn't exist yet
if ai.Assets == nil {
ai.Assets = map[string]Asset{}
}
// And store the asset in the map under the key k.
ai.Assets[k] = asset
}
}
/* handle err if non-nil */
}
这比一次Decode调用要多得多,但它基本上应该做正确的事情。
如果所有这些都在一个返回的函数中,(*AssetInfo, error)那么正确的替代方法/* Handle err */可能是
if err != nil {
return nil, err
}
- 2 回答
- 0 关注
- 148 浏览
添加回答
举报