map [string] interface {}和interface {}之间的区别

Trầ*_* Dự 4 interface go go-map

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

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

fmt.Println(migrations["create_user"])
Run Code Online (Sandbox Code Playgroud)

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

var migrations interface{}
json.Unmarshal(raw, &migrations)

// compile wrong here
fmt.Println(migrations["create_user"])
Run Code Online (Sandbox Code Playgroud)

我不明白很多关于之间的差异map[string]interface{},并interface{}在上述情况下。

mae*_*ics 11

这两种类型之间的区别就是看上去的样子:

  1. interface{}是“ any”类型,因为所有类型都实现了没有功能的接口。

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

当将字节数组从JSON解组到内存时,使用该interface{}类型最容易,因为它可以存储任何类型的JSON文档(对象,数组,基元等);但是,可能需要更多反射才能处理基础数据。map[string]interface{}当您知道JSON文档是一个对象时,[]interface{}通常使用a;而当您知道该文档是数组时,则很常见。

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


Him*_*shu 6

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

根据GoLang规范

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

x.(T)
Run Code Online (Sandbox Code Playgroud)

断言x不为nil,并且x中存储的值的类型为T。符号x。(T)称为类型断言。

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

var migrations interface{}
json.Unmarshal(raw, &migrations)

fmt.Println(migrations.(interface{}).(map[string]interface{})["create_user"])
Run Code Online (Sandbox Code Playgroud)

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