解组json时处理不同类型 [英] Handling different types when unmarshalling a json
问题描述
我正在使用一个端点(我不拥有并且无法修复),并且该端点返回JSON.
I'm consuming an endpoint (which I don't own and I cannot fix) and this endpoint returns JSON.
问题在于此JSON可以采用不同的格式:
The problem is this JSON can come in different formats:
格式1:
{
"message": "Message"
}
或
{
"message": ["ERROR_CODE"]
}
取决于发生的事情.
我希望有一个结构来保存此响应,因此以后我可以检查message
是字符串还是数组,并正确地遵循流程.
I'd like to have one struct to hold this response so later I can check if the message
is a string or array, and properly follow a flow.
可以在Go中做到吗?我认为的第一种方法是具有两个结构,并尝试使用string
解码为一个,如果发生错误,请尝试使用array
解码为一个.
Is it possible to do it in Go? The first approach I thought was to have two structs and try to decode to the one with string
, and if an error happens, try to decode to the one with array
.
有没有更优雅的方法?
推荐答案
将其解组为interface{}
类型的值,并使用类型断言或类型开关以检查类型价值最终.请注意,默认情况下,JSON数组未编组为[]interface{}
类型的值,因此您必须检查该值以检测错误响应.
Unmarshal it into a value of interface{}
type, and use a type assertion or type switch to inspect the type of value it ends up. Note that by default JSON arrays are unmarshaled into a value of type []interface{}
, so you have to check for that to detect the error response.
例如:
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)
}
}
}
输出(在游乐场上尝试):
Success, message: Message
Error, code: [ERROR_CODE]
这篇关于解组json时处理不同类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!