【问题标题】:Any difference in using an empty interface or an empty struct as a map's value?使用空接口或空结构作为映射的值有什么区别?
【发布时间】:2014-03-31 19:09:53
【问题描述】:

我正在使用这个构造来模拟一个集合

type MyType uint8
map[MyType]interface{}

然后我添加我所有的键并将它们映射到nil

我知道也可以使用

map[MyType]struct{}

使用空结构与interface{} 相比的任何好处。

【问题讨论】:

标签: go


【解决方案1】:

内存使用情况。例如,类型 struct{}interface{}bool

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var s struct{}
    fmt.Println(unsafe.Sizeof(s))
    var i interface{}
    fmt.Println(unsafe.Sizeof(i))
    var b bool
    fmt.Println(unsafe.Sizeof(b))
}

输出(32 位架构的字节数):

0
8
1

输出(64 位架构的字节数):

0
16
1

参考资料:

Go Data Structures: Interfaces

【讨论】:

  • 这对地图的内存使用有何影响?它会在内部为值的 struct{} 类型分配什么?
  • @DanielWilliams:Go 地图存储键和元素值。 struct{} 元素值占用零字节。
  • 我猜这会导致map[struct{}]struct{} 发生什么?它会有一个大小为零的键和一个大小为零的值,但你可以放 1 个东西(大小也为零)。
  • @DanielWilliams:使用 bool 类型而不是 map 类型。
【解决方案2】:

空结构体和空接口虽然在语法上相似,但实际上是对立的。一个空结构包含 no 数据;空接口可以保存任何类型的值。如果我看到map[MyType]struct{},我会立即知道不会存储任何值,只会存储键。如果我看到map[MyType]interface{},我的第一印象会是它是一个异构的值集合。即使我看到其中存储 nil 的代码,我也无法确定其他一些代码不会在其中存储其他内容。

换句话说,使用struct{} 使您的代码更具可读性。如另一个答案中所述,它还节省了一点内存,但这只是使用正确工具完成工作的附带好处。

【讨论】:

  • map[MyType]bool 呢?
  • 我自己实际上倾向于使用map[MyType]bool,因为它可以直接在if 条件下使用,并且它可能会产生最易读的代码。但是 OP 只询问了structinterface,我想让我的回答保持简单。 (而map[MyType]struct{} 是公认的集合成语。)
【解决方案3】:

我想添加有关空结构的更多详细信息,因为 andybalholm 和 peterSO 已经涵盖了差异。

下面的例子展示了空结构的可用性。

使用指针地址创建矩形结构的实例 运算符用 & 符号表示。

package main

import "fmt"

type rectangle struct {
    length  int
    breadth int
    color   string
}

func main() {
    var rect1 = &rectangle{10, 20, "Green"} // Can't skip any value
    fmt.Println(rect1)

    var rect2 = &rectangle{}
    rect2.length = 10
    rect2.color = "Red"
    fmt.Println(rect2) // breadth skipped

    var rect3 = &rectangle{}
    (*rect3).breadth = 10
    (*rect3).color = "Blue"
    fmt.Println(rect3) // length skipped
}

参考:https://www.golangprograms.com/go-language/struct.html

您可以参考:https://dave.cheney.net/2014/03/25/the-empty-struct

【讨论】:

    猜你喜欢
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2023-03-11
    • 2016-11-08
    • 2011-05-03
    • 1970-01-01
    • 2016-05-01
    相关资源
    最近更新 更多