Set of structs in Go

Issue

If I have a number of structs that I want to store:

type Stuff struct {
    a string
    b string
}

I can do it with a slice, but it seems like it would use less memory to use a proper set structure.

Unfortunately Go doesn’t have a set structure. Everyone recommends using map[Stuff]struct{} but that doesn’t work because Stuff is a struct. Anyone have any good solutions? Ideally without having to download a library.

Solution

Usually set and map data structures require more memory than storing a list of values in plain array or slice as set and map provide additional features efficiently like uniqueness or value retrieval by key.

If you want minimal memory usage, simply store them in a slice, e.g. []Stuff. If you use the values in multiple places, it might also be profitable to just store their pointers, e.g. []*Stuff and so each places that store the same Stuff values can store the same pointer (without duplicating the value).

If you only want to store unique struct values, then indeed the set would be the most convenient choice, in Go realized with a map.

There’s nothing wrong with map[Stuff]struct{}, it works. The requirement for the key type for maps:

The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.

Stuff is a struct, and structs in Go are comparable if:

Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.

If your Stuff struct is what you posted, it is comparable: it only contains fields of the comparable type string.

Also note that if you want a set data structure, it’s clearer if you use bool as the value type (e.g. map[Stuff]bool) and true as the value, and then you can simply use indexing to test if a value is in the map as the index expression yields the zero value of the value type (false for bool) if the key (Stuff in your case) is not in the map, properly telling the value you’re looking for is not in the “set”. (And if it is in the map, its associated true value is the result of the index expression – properly telling it is in the map).

Answered By – icza

Answer Checked By – David Marino (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.