2 回答

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超6個(gè)贊
你會(huì)因?yàn)榈谝粋€(gè)錯(cuò)誤而自責(zé)——你的 JSON 有,result但你的 struct 標(biāo)簽有response.
第二個(gè)問(wèn)題比較棘手。問(wèn)題是您聲明您的Asset地圖作為名為“資產(chǎn)”的鍵嵌套在結(jié)果中,但事實(shí)并非如此。其實(shí)它只是所有結(jié)果的按鍵其他比成功/錯(cuò)誤。不幸的是,encoding/json沒(méi)有任何方式來(lái)表達(dá)這一點(diǎn)。你可以說(shuō)它result是 a map[string]interface{},然后成功/錯(cuò)誤(如果它們存在)將是 bool/string,并且資產(chǎn)將更多map[string]interface{}s 包含所有其他字段的鍵。這是可行的,但它有點(diǎn)丑陋/效率低下,如果您想轉(zhuǎn)換為適當(dāng)?shù)慕Y(jié)構(gòu)類型以便您可以在其上擁有方法,則需要做很多工作。
也許更好的方法是解碼成這種類型:
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調(diào)用要多得多,但它基本上應(yīng)該做正確的事情。
如果所有這些都在一個(gè)返回的函數(shù)中,(*AssetInfo, error)那么正確的替代方法/* Handle err */可能是
if err != nil {
return nil, err
}
- 2 回答
- 0 關(guān)注
- 186 瀏覽
添加回答
舉報(bào)