我正在使用一个端点(我不拥有,我无法修复),这个端点返回JSON。
问题是这个JSON可以有不同的格式:
格式1:
{ “消息”:“消息”}要么
{ ” …
我建议为其创建一个不同的类型 的 信息 强> 并实现这一目标 json.Unmarshaller
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"` }
您可以找到带有测试的完整代码 这里
您可以使用实现的自定义类型 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{} 并且稍后键入断言,因为所有类型检查都封装在解组步骤中。
interface{}
对于一个真实的例子,看看我的 type veryFlexibleUint64 : https://github.com/sapcc/limes/blob/fb212143c5f5b3e9272994872fcc7b758ae47646/pkg/plugins/client_ironic.go
type veryFlexibleUint64