What's the difference? Is map[T]bool
optimized to map[T]struct{}
? Which is the best practice in Go?
Perhaps the best reason to use map[T]struct{}
is that you don't have to answer the question "what does it mean if the value is false
"?
From "The Go Programming Language":
The struct type with no fields is called the empty struct, written
struct{}
. It has size zero and carries no information but may be useful nonetheless. Some Go programmers use it instead of bool as the value type of a map that represents a set, to emphasize that only the keys are significant, but the space saving is marginal and the syntax more cumbersome, so we generally avoid it.
If you use bool
testing for presence in the "set" is slightly nicer since you can just say:
if mySet["something"] {
/* .. */
}
An empty struct is a struct type like any other. All the properties you are used to with normal structs apply equally to the empty struct. You can declare an array of structs{}
s, but they of course consume no storage.
var x [100]struct{}
fmt.Println(unsafe.Sizeof(x)) // prints 0
If empty structs hold no data, it is not possible to determine if two struct{}
values are different.
Considering the above statements it means that we may use them as method receivers.
type S struct{}
func (s *S) addr() { fmt.Printf("%p
", s) }
func main() {
var a, b S
a.addr() // 0x1beeb0
b.addr() // 0x1beeb0
}
Difference is in memory requirements. Under the bonnet empty struct is not a pointer but a special value to save memory.