Какой размер пустой структуры (`struct{}`) в Go и где она используется?

Ответ

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

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var e struct{}
    fmt.Println(unsafe.Sizeof(e)) // Вывод: 0
}

Основные применения:

  1. Сигнализация в каналах: Используется для отправки сигнала о событии без передачи данных. Это более явно и эффективно, чем отправлять bool или int.

    done := make(chan struct{})
    go func() {
        // ... какая-то работа ...
        done <- struct{}{}
    }()
    <-done // Ожидаем завершения работы
  2. Реализация множества (Set) через map: Когда нужно хранить только ключи, а значения не важны. map[string]struct{} эффективнее по памяти, чем map[string]bool.

    set := make(map[string]struct{})
    set["apple"] = struct{}{}
    set["orange"] = struct{}{}

Важный нюанс (выравнивание памяти): Хотя сама пустая структура имеет нулевой размер, если она является полем внутри другой структуры, она может косвенно увеличить её размер из-за правил выравнивания памяти. Однако, если она не является последним полем, компилятор часто может оптимизировать её размещение.

// Размер этой структуры будет равен размеру int32 (4 байта на 64-битной системе)
// Пустая структура не добавляет размера.
type S1 struct {
    field1 struct{}
    field2 int32
}

// А здесь размер может быть больше из-за выравнивания для следующего поля
// или если это последнее поле.
type S2 struct {
    field1 int32
    field2 struct{}
}