代码之家  ›  专栏  ›  技术社区  ›  Trần Kim Dá»±

映射[字符串]接口{}和接口{}之间的差异

  •  13
  • Trần Kim Dá»±  · 技术社区  · 7 年前

    我想将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"])
    

    我不太明白 映射[字符串]接口{} 接口{} 在上述情况下。

    2 回复  |  直到 7 年前
        1
  •  36
  •   maerics    7 年前

    这两种类型之间的区别只是表面上的不同:

    1. interface{} 是“any”类型,因为 全部的 类型实现没有函数的接口。

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

    将JSON中的字节数组解组到内存中时,最容易使用 接口{} 类型,因为它可以存储任何类型的JSON文档(对象、数组、原语等);然而,它可能需要更多的反射来处理底层数据。使用 映射[字符串]接口{} 当您知道JSON文档是一个对象并且 []interface{} 当您知道文档是一个数组时,这种情况很常见。

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

        2
  •  13
  •   Himanshu    7 年前

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

    根据 GoLang 规格

    对于接口类型为x且类型为T的表达式,主 表示

    x.(T)
    

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

    而且 Unmarshal 函数需要指向的指针 migration 类型为接口{}或映射[字符串]接口{}

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

    自从 migrations 不是地图。因此,不能使用其键来获取值。接口{}没有键