Any difference in using an empty interface or an empty struct as a map's value?

huangapple go评论95阅读模式
英文:

Any difference in using an empty interface or an empty struct as a map's value?

问题

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

type MyType uint8
map[MyType]interface{}

然后我将所有的键都映射到nil

我了解到也可以使用

map[MyType]struct{}

相比于使用interface{},使用空结构体有什么好处呢?

英文:

I am using this construct to simulate a set

type MyType uint8
map[MyType]interface{}

I then add in all my keys and map them to nil.

I've learnt that it is also possible to use

map[MyType]struct{}

Any benefits of using the empty struct versus interface{}.

答案1

得分: 48

内存使用情况。例如,类型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数据结构:接口

英文:

Memory usage. For example, types struct{}, interface{}, and 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))
}

Output (bytes for 32-bit architecture):

0
8
1

Output (bytes for 64-bit architecture):

0
16
1

References:

Go Data Structures: Interfaces

答案2

得分: 36

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

换句话说,使用struct{}可以使你的代码更易读。它还可以节省一些内存,正如其他答案中所描述的,但这只是使用正确工具的附加好处。

英文:

The empty struct and empty interface, though syntactically similar, are actually opposites. An empty struct holds no data; an empty interface can hold any type of value. If I see a map[MyType]struct{}, I know immediately that no values will be stored, only keys. If I see a map[MyType]interface{}, my first impression will be that it is a heterogenous collection of values. Even if I see code storing nil in it, I won't know for sure that some other piece of code doesn't store something else in it.

In other words, using struct{} makes your code much more readable. It also saves a little memory, as described in the other answer, but that is just a fringe benefit of using the right tool for the job.

答案3

得分: 2

我想补充一些关于空结构体的细节,因为andybalholm和peterSO已经涵盖了差异。

下面是一个示例,展示了空结构体的可用性。

通过使用指针地址运算符&创建一个矩形结构体的实例。

package main

import "fmt"

type rectangle struct {
    length  int
    breadth int
    color   string
}

func main() {
    var rect1 = &rectangle{10, 20, "Green"} // 不能跳过任何值
    fmt.Println(rect1)

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

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

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

如果你想深入阅读,可以参考:https://dave.cheney.net/2014/03/25/the-empty-struct

英文:

I would like to add additional detail about empty struct , as differences are already covered by andybalholm and peterSO .

Below is the example which shows usability of empty struct .

> Creates an instance of rectangle struct by using a pointer address
> operator is denoted by & symbol.

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
}

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

For a thorough read you can refer : https://dave.cheney.net/2014/03/25/the-empty-struct

huangapple
  • 本文由 发表于 2014年4月1日 03:09:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/22770114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定