亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 GO 中反序列化一個非標準的 json

在 GO 中反序列化一個非標準的 json

Go
www說 2022-06-27 15:20:33
我正在編寫一個簡單的應用程序,它向返回類型的異構 JSON 的 API 發出請求{  "results": [    [123, "Zho's Mask", 10586],    [345, "Ravaging Superior Studded Coat", 58]  ]}最終,我希望能夠使用結果響應中的特定索引。例如,我希望能夠獲得“Zho's Mask”,或者價格:10586。這是我正在使用的 API GW2TP。GO JSON 博客中的大多數示例都引用了不包含嵌套數組的更簡單或直接的 JSON。根據我的閱讀,由于我知道 JSON 響應的一般外觀,我可以制作一個 GO 結構并將其解組為該結構的一個實例。但是,我無法為這項工作創建正確的結構。這是我目前創建適當結構的嘗試package mainimport (    "encoding/json"    "fmt"    "io/ioutil"    "log"    "net/http")// {"results":[[123,"Zho's Mask",3532]]}type Equipment struct {    Results []ResArray}type ResArray struct {    Medium []LastArray}type LastArray struct {    Info string}func main() {    res, err := http.Get("http://api.gw2tp.com/1/items?ids=123&fields=name,sell")    if err != nil {        log.Fatal(err)    }    var equipment Equipment    data, err := ioutil.ReadAll(res.Body)    if err != nil {        fmt.Print("ReadAll Error: ", err, "\n")    }    err = json.Unmarshal(data, &equipment)    if err != nil {        fmt.Print("Unmarshal error: ", err, "\n")    }}這是解組錯誤:Unmarshal error: json: cannot unmarshal array into Go struct field Equipment.Results of type main.ResArray最后,這是我目前 在 Golang an Introduction 中實現所需的 GO 結構 JSON方法的靈感。
查看完整描述

1 回答

?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

類型 ResArray 結構 {


但它不是結構,而是切片!


type LastArray struct {

    Info string

}

但它不是字符串,有時是字符串,有時是數字。


執行此操作的簡單方法是將您的類型定義為


type Equipment struct {

    Results [][]interface{}

}

它說結果包含一片……某物。您可以命名中間類型,但這不是必需的。那么例如e.Results[0][1].(string)將是"Zho's Mask"。


更好的方法是通過提供一個 custom來實現UnmarshalerUnmarshalJSON接口,如下所示:


type Equipment struct {

    Results []Item

}


type Item struct {

    ID int

    Name string

    Sell int

}


func (i *Item) UnmarshalJSON(b []byte) error {

    // We're deserializing into a struct, but in JSON it's a mixed-type array.

    var arr []interface{}

    err := json.Unmarshal(b, &arr)

    if err != nil {

        return fmt.Errorf("unmarshal Item underlying array: %w", err)

    }

    if len(arr) != 3 {

        return fmt.Errorf("Item underlying array should be 3 elements, got %d", len(arr))

    }


    // JSON numbers will become float64 when loaded into interface{} but we want int

    id, ok := arr[0].(float64)

    if !ok {

        return fmt.Errorf("expected float64 for Item.ID, got %T", arr[0])

    }

    i.ID = int(id)


    i.Name, ok = arr[1].(string)

    if !ok {

        return fmt.Errorf("expected string for Item.Name, got %T", arr[1])


    }


    sell, ok := arr[2].(float64)

    if !ok {

        return fmt.Errorf("expected float64 for Item.Sell, got %T", arr[2])

    }

    i.Sell = int(sell)

    return nil

}

請記住,這些類型與您向 API 請求的確切字段列表結合在一起——如果您更改它,您將不得不更改類型和從數組加載它的解組函數。


查看完整回答
反對 回復 2022-06-27
  • 1 回答
  • 0 關注
  • 221 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號