簡體   English   中英

解碼 Go 中的動態字段

[英]Decoding a dynamic field in Go

我收到來自外部 API 的響應,該字段的字段可以有 2 個值:

{"field": []}

或者

{"field": {"key1": "value", "key2": "value"}}

我將結構設置為

type Object Struct {
   Field map[string]string `json:"field,omitempty"`
}

然后調用我自己實現的 function 來解碼響應

func decode(response *http.Response) (*Object, error) {
    var response Object
    err := json.NewDecoder(response.Body).Decode(&response)
    if err != nil {
        return nil, err
    }

    return &response, nil
}

但這僅適用於第二個響應(當字段不為空時)。 對於第一個響應,我得到一個錯誤。

重命名decode function 中的變量response 由於聲明的 function 參數和變量同名,因此會造成混淆。

您可以為Field執行自定義封送拆收器類型。 例子:

type keys struct {
        Key1 string
        Key2 string
}

type mytype struct {
        EmptySlice bool
        Keys       *keys
}

func (m *mytype) UnmarshalJSON(b []byte) error {
        if bytes.Equal(b, []byte("[]")) {
                m.EmptySlice = true
                return nil
        }

        m.Keys = &keys{}
        return json.Unmarshal(b, &m.Keys)
}

type Object struct {
        Field mytype `json:"field"`
}

func main() {
        input := []string{
                `{"field": []}`,
                `{"field": {"key1": "value", "key2": "value"}}`,
        }

        for i, s := range input {
                var o Object

                err := json.Unmarshal([]byte(s), &o)
                if err != nil {
                        log.Fatal(err)
                }

                fmt.Printf("%d: %+v\n", i+1, o)
        }
}

https://go.dev/play/p/OqSKfUXHFyb

您可以使用自定義類型並在該類型上實現 UnmarshalJSON 接口方法。

例如:

type Field struct {
    arr []string
    m   map[string]string
}

func (f *Field) UnmarshalJSON(b []byte) error {
    var m map[string]string
    err := json.Unmarshal(b, &m)
    if err == nil {
        f.m = m
        return nil
    }

    var arr []string
    err = json.Unmarshal(b, &arr)
    if err == nil {
        f.arr = arr
        return nil
    }

    return fmt.Errorf("type of property not array or map")
}

https://go.dev/play/p/JuFE--hWAjw

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM