ProgrammingBackend Developer

What is an empty struct struct{} in Go and when should it be used? What are the capabilities and nuances of working with it, especially in the context of memory optimization and implementing sets or signaling channels?

Pass interviews with Hintsage AI assistant

Answer

In Go, the struct{} type represents a structure with no fields and takes up 0 bytes of memory. This is a valuable feature used to minimize resource consumption in cases where the mere presence of something matters, but no data is needed — for instance, in the implementation of sets, signaling structures, or event channels.

Example usage for a set:

mySet := make(map[string]struct{}) mySet["foo"] = struct{}{} if _, ok := mySet["foo"]; ok { fmt.Println("foo is present in mySet") }
  • struct{} is used as a value to indicate the presence of a key.
  • Unlike map[string]bool, the variant with struct{} is more memory-efficient.

Signaling channels:

done := make(chan struct{}) // The goroutine waits for a completion signal <-done
  • Such a channel simply sends an event, not data.

Trick question

What is the difference between map[string]struct{} and map[string]bool when implementing a set? Why is map[string]struct{} preferable and does it have any downsides?

Answer:

  • map[string]struct{} uses 0 bytes per value, making it the most compact option — it saves memory, especially with a large amount of data.
  • map[string]bool requires 1 byte per value (internally it may take more memory due to alignment).
  • In both versions, the logic is the same — the value doesn’t matter, only the presence of the key does.
  • A downside of map[string]struct{}: it is not possible to quickly get a list of all values marked true, if a boolean value is needed. It still requires iterating over the keys.

Example:

set := make(map[string]struct{}) set["Alice"] = struct{}{} _, exists := set["Alice"] // true flags := make(map[string]bool) flags["Alice"] = true _, exists := flags["Alice"] // true

Examples of real mistakes due to ignorance of the topic nuances


Story

In a project for storing unique identifiers, they used map[string]bool, which led to a significant increase in memory consumption with data growth — hundreds of megabytes compared to the map[string]struct{} option. Switching to struct{} reduced memory usage by more than half.


Story

A beginner signaled the completion of a goroutine using chan bool. With a large number of goroutines, value passing became excessive: it was never analyzed whether true or false was received. Switching to chan struct{} revealed architectural inaccuracies and helped simplify the code.


Story

In a library, a set was implemented using a map where the value was a string. This took up too much memory. After a Code Review, it was switched to map[type]struct{}. The error was discovered after analyzing the memory profile during load testing, when the application crashed due to OOM.