3 回答
TA贡献1877条经验 获得超1个赞
将其解组为类型值interface{}
,并使用类型断言或类型开关来检查最终值的类型。请注意,默认情况下,JSON 数组被解组为 type 的值[]interface{}
,因此您必须检查它以检测错误响应。
例如:
type Response struct {
Message interface{} `json:"message"`
}
func main() {
inputs := []string{
`{"message":"Message"}`,
`{"message":["ERROR_CODE"]}`,
}
for _, input := range inputs {
var r Response
if err := json.Unmarshal([]byte(input), &r); err != nil {
panic(err)
}
switch x := r.Message.(type) {
case string:
fmt.Println("Success, message:", x)
case []interface{}:
fmt.Println("Error, code:", x)
default:
fmt.Println("Something else:", x)
}
}
}
输出(在Go Playground上尝试):
Success, message: Message
Error, code: [ERROR_CODE]
TA贡献1891条经验 获得超3个赞
您可以使用自定义类型依次实现json.Unmarshaller并尝试解码每种可能的输入格式:
type Message struct {
Text string
Codes []int
}
func (m *Message) UnmarshalJSON(input []byte) error {
var text string
err := json.Unmarshal(input, &text)
if err == nil {
m.Text = text
m.Codes = nil
return nil
}
var codes []int
err := json.Unmarshal(input, &codes)
if err == nil {
m.Text = nil
m.Codes = codes
return nil
}
return err
}
我更喜欢这种方法,而不是稍后解组interface{}和类型断言,因为所有类型检查都封装在解组步骤中。
TA贡献1811条经验 获得超6个赞
我建议为Message创建一个不同的类型并制作那个实现json.Unmarshaller
这是代码的样子
type message struct {
Text string
Codes []string //or int , assuming array of string as it was not mentioned in the question
}
func (m *message) UnmarshalJSON(input []byte) error {
if len(input) == 0 {
return nil
}
switch input[0] {
case '"':
m.Text = strings.Trim(string(input), `"`)
return nil
case '[':
return json.Unmarshal(input, &m.Codes)
default:
return fmt.Errorf(`invalid character %q looking for " or [`, input[0])
}
}
type Error struct {
Message message `json:"message"`
}
- 3 回答
- 0 关注
- 160 浏览
添加回答
举报