Go 将接口{}从JSON转换为多种具体类型之一
我一直在四处寻找这个问题的解决方案,但在这里一直找不到。我不确定这是否可能,但值得一问 我有一个接口,我的应用程序从服务器读取JSON数据。可能会返回响应的类型很少,所以我使用Go 将接口{}从JSON转换为多种具体类型之一,go,interface,Go,Interface,我一直在四处寻找这个问题的解决方案,但在这里一直找不到。我不确定这是否可能,但值得一问 我有一个接口,我的应用程序从服务器读取JSON数据。可能会返回响应的类型很少,所以我使用interface{}来使用它 在将json字节解组到接口{}之后,如何将其转换为具体类型?如果失败,我想检查下一种对话类型,直到对话成功 它看起来像这样(为了简洁起见删除了一些代码) type foorer接口{ Foo() } 键入结构{} func(a*a)Foo(){..} 类型B结构{} func(b*b)Foo
interface{}
来使用它
在将json字节解组到接口{}
之后,如何将其转换为具体类型?如果失败,我想检查下一种对话类型,直到对话成功
它看起来像这样(为了简洁起见删除了一些代码)
type foorer接口{
Foo()
}
键入结构{}
func(a*a)Foo(){..}
类型B结构{}
func(b*b)Foo(){..}
//resp是io.ReadCloser
func重量级软件(resp){
var parsedResp接口{}
bytesData,err:=ioutil.ReadAll(resp)
Unmarshal(bytesData,parsedResp)
//将parsedResp转换为具体类型,它可能是a或B结构
//试试A,如果失败,试试B。
...
concreteType.Foo()
}
我已经检查了类型断言和类型转换,但无法使其正常工作
围棋可以吗
JSON响应内容示例
A:
{
"data": {
"access_key": "AKIA...",
"secret_key": "xlCs...",
}
}
B:
{
"data": {
"data": {
"foo": "bar"
},
"metadata": {
...
}
}
}
你有选择。没有一个是完美的 一个是,如前所述,只需查看地图内部的钥匙。我写了一个这样的例子。它的目的是要有教育意义,但不是特别有效率或任何东西 另一种方法是使用
json.RawMessage
稍微延迟解析。我写了一个这样的例子。请注意,我是如何求助于解码器中各种struct
s的指针成员的。这会让事情变得烦人:您可能只想为解码使用指针化的数据类型,而在选择类型后使用非指针类型。但它确实允许您直接(通过struct标记)使用更多的json包
还有一种方法是使用
json.NewDecoder
来获取流解码器,并对其进行处理。这可能是最健壮的方法,但也是最棘手的。如何将其转换为具体类型?--手动。由于您正在使用interface{}
作为解组的目标,因此结果将是map[string]interface{}
或[]interface{}
或某些原语。因此,将您的parsedResp
,将assert键入其中一种可能的类型,然后每个元素(如果有)都会这样做,依此类推。。。然后从你收集的数据中构建具体的类型。或者首先不要使用接口{}
。什么结构interface{}
不是一个结构,执行json.Unmarshal(data,&dest)
其中dest的类型为interface{}
且没有初始化的动态类型,将无法神奇地看出您想要a
或B
。i、 e.parseResp
中没有结构。如果您解组到并interface{}
中,您将获得JSON对象的map[string]interface{}
。您需要从中进行转换,或者直接解组到正确的具体类型。@ChenA。是的,如果数据
像您显示的那样随机,并且您无法预先知道json字节代表的具体类型,那么您必须做一件难看的事情,在map[string]interface{}
中摸索。请参阅,以获取有关解组未知类型的一些提示。感谢提供详细的示例。我正在考虑重构它。有一个通用结构来解析json(如第二个示例),然后根据预期的内容确定它是哪个结构。你有一个json.NewDecoder
的例子吗?没有,NewDecoder看起来是最棘手的一个,我就停在这一点上了。:-)