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

后端 未结 3 1139
南方客
南方客 2020-12-13 06:36

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

相关标签:
3条回答
  • 2020-12-13 07:29

    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

    0 讨论(0)
  • 2020-12-13 07:29

    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.

    0 讨论(0)
  • 2020-12-13 07:29

    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

    0 讨论(0)
提交回复
热议问题