Why there is no container/set

1,318 views
Skip to first unread message

James Chow

unread,
Dec 3, 2011, 4:32:02 AM12/3/11
to golang-nuts
I used "set" in java and c++, why there is no such container in golang pkg-tree?

Vanja Pejovic

unread,
Dec 3, 2011, 4:36:07 AM12/3/11
to James Chow, golang-nuts
It's not ideal, but map[T]bool serves as a good replacement most of the time.

chris dollin

unread,
Dec 3, 2011, 4:36:28 AM12/3/11
to James Chow, golang-nuts

You could use a map.

James Chow

unread,
Dec 3, 2011, 4:38:24 AM12/3/11
to golang-nuts
> It's not ideal, but map[T]bool serves as a good replacement most of the
> time.

Thanks, that's a good idea!

Kyle Lemons

unread,
Dec 3, 2011, 4:41:58 AM12/3/11
to James Chow, golang-nuts
Thanks, that's a good idea!

If you don't need the bool, you can use map[key]struct{}, because a struct{} takes no space and has no value.  Then you use the "_, ok := x[k]" notation to check if a key is set.

Rémy Oudompheng

unread,
Dec 3, 2011, 4:42:38 AM12/3/11
to golang-nuts

I usually define "type None struct{}" and use map[T]None. I'm not familiar
enough with the implementation of 0-byte structs to know whether it i
more memory-efficient.

Rémy.

Kyle Lemons

unread,
Dec 3, 2011, 4:59:11 AM12/3/11
to Rémy Oudompheng, golang-nuts
I usually define "type None struct{}" and use map[T]None. I'm not familiar
enough with the implementation of 0-byte structs to know whether it i
more memory-efficient.

I don't think the current compilers optimize a map[key]struct{} to be as efficient as a hash set, but from my limited understanding []struct{} and chan struct{} are more efficient.

Idiomatically, you probably don't want to name a struct{} "None" for the same reasons you don't want to name an interface{} "Value" -- it tends to make code less clear instead of more.

kortschak

unread,
Dec 4, 2011, 5:33:57 AM12/4/11
to golang-nuts
If you define a type None struct{}, then you can x[k] = None{}. It's
not possible as far as I can see to x[k] = struct{}, it seems you need
to get the value by var none struct{}. It there a less redundant way
to do this?

Rémy Oudompheng

unread,
Dec 4, 2011, 6:52:08 AM12/4/11
to kortschak, golang-nuts
On 2011/12/4 kortschak <dan.ko...@adelaide.edu.au> wrote:
> If you define a type None struct{}, then you can x[k] = None{}. It's
> not possible as far as I can see to x[k] = struct{}, it seems you need
> to get the value by var none struct{}. It there a less redundant way
> to do this?
>

Yes, if you don't want you define None, you'll need to write struct{}{}
to get a value of type struct{}.

Rémy.

Dan Kortschak

unread,
Dec 4, 2011, 3:50:13 PM12/4/11
to Rémy Oudompheng, golang-nuts
Mmm. Thinking about it logically (should do this more often), that's
obvious since None would be essentially algebraically replaced by
struct{}.

thanks
Dan

Andrew Gerrand

unread,
Dec 4, 2011, 5:29:17 PM12/4/11
to golan...@googlegroups.com, James Chow


On Saturday, December 3, 2011 8:41:58 PM UTC+11, Kyle Lemons wrote:
Thanks, that's a good idea!

If you don't need the bool, you can use map[key]struct{}, because a struct{} takes no space and has no value.  Then you use the "_, ok := x[k]" notation to check if a key is set.

I prefer map[T]bool because it is syntactically a lot nicer.

m[v] = true
if m[v] {
   // v is in m
}

I don't think you'll see any efficiency benefit using struct{} with the current implementation.

Andrew 

buchan...@gmail.com

unread,
Dec 31, 2016, 12:58:47 AM12/31/16
to golang-nuts
Back to the original question, container/set seems like a great addition. It could have a nicer interface than map[T]U and a single best implementation. Can we talk about whether the owners of that package agree?

Konstantin Khomoutov

unread,
Dec 31, 2016, 10:06:27 AM12/31/16
to buchan...@gmail.com, golang-nuts
On Fri, 30 Dec 2016 11:26:16 -0800 (PST)
buchan...@gmail.com wrote:

> On Saturday, December 3, 2011 at 1:32:02 AM UTC-8, James Chow wrote:
> >
> > I used "set" in java and c++, why there is no such container in
> > golang pkg-tree?
> >
> Back to the original question, container/set seems like a great
> addition. It could have a nicer interface than map[T]U and a single
> best implementation. Can we talk about whether the owners of that
> package agree?

I may be wrong, but I think it's actually about Go not having generics:
since map[T]U has built-in support from the compiler (as you can see,
it is generic as its type is parameterized by T and U), you can use
it easily. On the contrary, the prospective container/set *module*
cannot expect this level of support from the compiler (it doesn't
matter this module would have been provided as part of the runtime), so
it would have to define all its methods in the terms of the interface{}
type, and with that you will require the users of the package do type
conversions when using it.

Please look at the existing container/list module: while I do find it
useful, quite many people think adding it was a mistake: the amount of
boilerplate it can reduce for it could be balanced by the amount of it
to actually use the module.


Note that there exists 3rd-party projects like [1] which can be used
along with codegen support [2] to provide custom type-safe set
implementations for particular concrete types.

See also the more recent [3] which appears to use the stock
`go generate` command to achieve the same goal.

1. https://github.com/deckarep/golang-set
2. http://alikewise.com/gen/
3. https://github.com/ncw/gotemplate
Reply all
Reply to author
Forward
0 new messages