В каких случаях и для чего в Go используется пустая структура `struct{}`?

Ответ

Пустая структура struct{} — это тип данных, который не содержит полей и не занимает памяти (0 байт). Благодаря этому свойству она является идеальным инструментом для ситуаций, где важно передать сигнал или обозначить присутствие элемента, а не сами данные.

Основные сценарии использования:

  1. Для сигнализации в каналах. Когда нужно просто уведомить другую горутину о событии (например, о завершении работы), не передавая никаких данных. Это более явно и эффективно, чем отправлять bool или int.

    // Канал для сигнала о завершении
    done := make(chan struct{})
    
    go func() {
        // ... какая-то работа ...
        fmt.Println("Горутина завершила работу")
        // Отправляем сигнал в канал
        done <- struct{}{}
    }()
    
    // Ожидаем сигнала
    <-done 
    fmt.Println("Основная программа получила сигнал")
  2. Для реализации множества (Set) с помощью map. Чтобы создать множество, где важен только факт наличия ключа, в качестве значения в map используют пустую структуру. Это экономит память по сравнению с использованием bool или int в качестве значения.

    // Множество для хранения уникальных строк
    set := make(map[string]struct{})
    
    // Добавляем элемент
    set["apple"] = struct{}{}
    set["orange"] = struct{}{}
    
    // Проверяем наличие элемента
    if _, exists := set["apple"]; exists {
        fmt.Println("apple существует в множестве")
    }
  3. В качестве "заглушки" для реализации интерфейса. Если для реализации интерфейса не требуется хранить состояние, можно использовать методы с получателем (receiver) типа *struct{}.