[英]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)
}
}
您可以使用自定義類型並在該類型上實現 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")
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.