3 ms·
map[T]struct{} is the set type in Go. (Note that struct{} is represented with 0 bytes of memory, so it's not chaff.) You might like the slices proposal for ut
by jrockway 5y ago
map[T]struct{} is the set type in Go. (Note that struct{} is represented with 0 bytes of memory, so it's not chaff.)
You might like the slices proposal for utility functions like these: https://github.com/golang/go/issues/45955 https://github.com/golang/go/issues/45955
- woodruffw 5y agoThanks. I wasn't aware that struct{} is zero-sized, so that plugs that hole. I'll admit freely that I'm not a proficient Go programmer, so it's easier for me to see the things I don't like than the things that Gophers praise. But even this solution leaves me unsatisfied, in contrast to what I'd reach for in Rust or even C++: it requires that I know that struct{} is zero-sized, and I still have to do the manual legwork of writing a CS101 dedupe function.
- tialaramex 5y agoZero Size optimisations are a thing in Rust too though, and I don't think an empty struct being zero size is any more surprising than Rust's empty tuple being zero size. Like, if you tell Rust you want 4 million empty tuples in a vector, it will give you a vector with exactly 4 million empty tuples in it and no heap allocation because those empty tuples don't take space, so, 4 million of them also doesn't take up any space.
- woodruffw 5y agoThe key difference being knowledge: I don't have to know `HashSet` is really just a map with a ZST to use it efficiently. All I need to know is that I don't need a value, and the ecosystem obliges me. This in contrast to Go, where I need to know that `struct{}` is a ZST, that the "right" way to do a set is to use it as the map value, &c.
- typical182 5y agoThere is also a WIP Go proposal for adding a set to the standard library using the upcoming generics: https://github.com/golang/go/discussions/47331 https://github.com/golang/go/discussions/47331
- bombela 5y agoFun thing, is Rust employs the same trick. The HashSet<T> is an alias for HashMap<T, ()>. "()" is the unit type. Which is zero-sized. Because Rust has generics, it is more ergonomic though. https://doc.rust-lang.org/std/collections/struct.HashSet.html https://doc.rust-lang.org/std/collections/struct.HashSet.htm...