我正在编写一个JSON列表为空的测试.
{"matches": []}
Run Code Online (Sandbox Code Playgroud)
对象有类型map[string]interface{},我想测试列表是否为空.
var matches := response["matches"]
if len(matches) != 0 {
t.Errorf("Non-empty match list!")
}
Run Code Online (Sandbox Code Playgroud)
但是我在编译时告诉我这是无效的
invalid argument matches (type interface {}) for len
Run Code Online (Sandbox Code Playgroud)
如果我尝试转换为列表类型:
matches := response["matches"].([]string)
Run Code Online (Sandbox Code Playgroud)
我感到恐慌:
panic: interface conversion: interface is []interface {}, not []string [recovered]
Run Code Online (Sandbox Code Playgroud)
我想在这里写些什么?
jos*_*hlf 18
使用Go中的映射进行JSON解析时,无处不在使用接口.想象一下,你有以下JSON对象:
{
"stuff" : [
"stuff1",
"stuff2",
"stuff3",
]
}
Run Code Online (Sandbox Code Playgroud)
Go JSON库将外部对象解析为从键到值的映射,正如您在代码中看到的那样.它将变量名称映射为与这些变量名称对应的值的键.但是,由于它无法提前知道这些值是什么,因此地图的值类型很简单interface{}.所以,假设您知道有一个被调用的密钥"stuff",并且您知道它的值是一个数组.你可以这样做:
arr := myMap["stuff"]
Run Code Online (Sandbox Code Playgroud)
而且你知道它是一个数组类型,所以你实际上可以这样做:
arr := myMap["stuff"].([]interface{})
Run Code Online (Sandbox Code Playgroud)
这里的问题是,虽然你是对的,它是一个数组,而JSON库知道这一点,它无法知道每个元素都是类型的string,所以没有办法让它决定数组类型应该是是[]string.想象一下,如果你这样做了:
{
"stuff" : [
"stuff1",
"stuff2",
3
]
}
Run Code Online (Sandbox Code Playgroud)
好吧"stuff"现在不能是一个字符串数组,因为其中一个元素不是字符串.事实上,它不能是任何东西的数组- 没有一种类型可以满足所有元素的类型.这就是为什么Go JSON库别无选择,只能将其保留为[]interface{}.幸运的是,既然你想要的只是长度,你已经完成了.你可以这样做:
arr := myMap["stuff"].([]interface{})
l := len(arr)
Run Code Online (Sandbox Code Playgroud)
现在这一切都很好,但是让我们说你想要实际看到其中一个元素.您现在可以取出一个元素,并且知道它是一个字符串,执行:
arr := myMap["stuff"].([]interface{})
iv := arr[0] // interface value
sv := iv.(string) // string value
Run Code Online (Sandbox Code Playgroud)
注意
当我说"数组"时,我指的是JSON意义上的数组 - 这些是JSON数组.在Go中表示它们的数据结构称为"切片"(Go也有数组,但它们是一个单独的东西 - 如果您习惯使用C或Java等语言中的数组,则Go切片是最接近的模拟).