map[string]interface{} 和 interface{} 之間的差異



我想将 JSON 文件解析为map[string]interface{}

var migrations map[string]interface{}
json.Unmarshal(raw, &migrations)
fmt.Println(migrations["create_user"])

但是我修改了我的代码以将数据指向interface{}

var migrations interface{}
json.Unmarshal(raw, &migrations)
// compile wrong here
fmt.Println(migrations["create_user"])

在上述情况下,我对map[string]interface{}interface{}之间的区别不太了解。

这两种类型之间的区别就是它看起来的样子:

  1. interface{}是"any"类型,因为所有类型实现没有函数的接口。

  2. map[string]interface{}是一个映射,其键是字符串,值是任何类型的。

将字节数组从JSON解组到内存中时,最简单的方法是使用interface{}类型,因为它可以存储任何类型的JSON文档(对象,数组,原语等);但是,它可能需要更多的反射来处理基础数据。 当您知道 JSON 文档是一个对象时,使用map[string]interface{}很常见,当您知道文档是一个数组时[]interface{}使用很常见。

但是,解封 JSON 的最佳方法 - 尤其是当您提前知道文档的结构时 - 是定义和使用准确描述数据的自定义结构类型。这样,您可以避免任何反射并提高代码的可读性。

这是因为默认情况下你需要键入assert interface{}来获取map[string]interface{}的基础值。

根据 GoLang 规范

对于接口类型和类型 T 的表达式 x,主 表达

x.(T)

断言 x 不是 nil,并且存储在 x 中的值是 T 类型。 表示法 x.(T) 称为类型断言。

此外Unmarshal函数需要指向 interface{} 或 map[string]interface{} 类型的migration的指针

var migrations interface{}
json.Unmarshal(raw, &migrations)
fmt.Println(migrations.(interface{}).(map[string]interface{})["create_user"])

由于migrations不是地图。因此,您不能使用其密钥来获取值。接口{} 没有键

相关内容

  • 没有找到相关文章

最新更新