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 關注
- 214 瀏覽
添加回答
舉報
