解组 json 时处理不同类型

我正在使用一个端点(我不拥有并且无法修复)并且该端点返回 JSON。

问题是这个 JSON 可以有不同的格式:

格式一:

{ 
 "message": "Message"
 }

或者

{ 
 "message": ["ERROR_CODE"]
}

取决于发生了什么。

我想要一个结构来保存此响应,以便稍后我可以检查它是message字符串还是数组,并正确地遵循流程。

有可能在围棋中做到吗?我认为的第一种方法是有两个结构并尝试解码为带有 的结构string,如果发生错误,则尝试解码为带有 的结构array

有没有更优雅的方法?


守候你守候我
浏览 161回答 3
3回答

冉冉说

将其解组为类型值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: MessageError, code: [ERROR_CODE]

万千封印

您可以使用自定义类型依次实现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{}和类型断言,因为所有类型检查都封装在解组步骤中。

杨魅力

我建议为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"`}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go