[英]Decoding a dynamic field in Go
I get a response from an external API that has a field which can have 2 values:我收到来自外部 API 的响应,该字段的字段可以有 2 个值:
{"field": []}
or或者
{"field": {"key1": "value", "key2": "value"}}
I set the struct to be我将结构设置为
type Object Struct {
Field map[string]string `json:"field,omitempty"`
}
And then call my own implemented function to decode the response然后调用我自己实现的 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
}
But this works only for the second response ( when field not empty is).但这仅适用于第二个响应(当字段不为空时)。 For the first response I get an error.对于第一个响应,我得到一个错误。
Rename the variable response inside decode function.重命名decode function 中的变量response 。 Since both function argument & variable declared are of same name, it creates confusion.由于声明的 function 参数和变量同名,因此会造成混淆。
you can do a custom marshaler type for the Field
.您可以为Field
执行自定义封送拆收器类型。 Example:例子:
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 https://go.dev/play/p/OqSKfUXHFyb
You can use a custom type and implement the UnmarshalJSON interface method on that type.您可以使用自定义类型并在该类型上实现 UnmarshalJSON 接口方法。
For example:例如:
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 https://go.dev/play/p/JuFE--hWAjw
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.