为了账号安全,请及时绑定邮箱和手机立即绑定

解组 json 时处理不同类型

解组 json 时处理不同类型

Go
守候你守候我 2023-06-12 17:18:10
我正在使用一个端点(我不拥有并且无法修复)并且该端点返回 JSON。问题是这个 JSON 可以有不同的格式:格式一:{   "message": "Message"  }或者{   "message": ["ERROR_CODE"] }取决于发生了什么。我想要一个结构来保存此响应,以便稍后我可以检查它是message字符串还是数组,并正确地遵循流程。有可能在围棋中做到吗?我认为的第一种方法是有两个结构并尝试解码为带有 的结构string,如果发生错误,则尝试解码为带有 的结构array。有没有更优雅的方法?
查看完整描述

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]


查看完整回答
反对 回复 2023-06-12
?
万千封印

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{}和类型断言,因为所有类型检查都封装在解组步骤中。



查看完整回答
反对 回复 2023-06-12
?
杨魅力

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"`

}


查看完整回答
反对 回复 2023-06-12
  • 3 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信