Структуры

Создаём составные типы через struct и добавляем им методы.

struct — составной тип, группирующий поля под одним именем; в Zig структуры могут содержать и методы, а сами являются обычными значениями, которые можно присваивать константам.

Структура — основной способ объединить связанные данные. В Zig объявление структуры выглядит как присваивание её обычной переменной: const Point = struct { ... }. Это не случайность — типы в Zig тоже значения, и это краеугольный камень его метапрограммирования.

Объявление и создание

const std = @import("std");

const Point = struct {
    x: i32,
    y: i32,
};

pub fn main() void {
    const p = Point{ .x = 3, .y = 4 };
    std.debug.print("({d}, {d})\n", .{ p.x, p.y });
}

Вывод:

(3, 4)

Поля инициализируют по имени через точку: .x = 3. Порядок при этом не важен, а пропустить поле без значения по умолчанию нельзя — компилятор потребует заполнить все.

Методы внутри структуры

const Point = struct {
    x: i32,
    y: i32,

    fn distanceSquared(self: Point) i32 {
        return self.x * self.x + self.y * self.y;
    }
};
// вызов: p.distanceSquared()

Метод — это просто функция внутри структуры, первый параметр которой по соглашению называется self. Вызов p.distanceSquared() — синтаксический сахар для Point.distanceSquared(p). Никакого скрытого this: первый параметр виден явно.

Значения по умолчанию

const Config = struct {
    retries: u8 = 3,      // значение по умолчанию
    verbose: bool = false,
};

const c = Config{};       // оба поля возьмут умолчания
const c2 = Config{ .verbose = true }; // retries останется 3

Поле можно снабдить значением по умолчанию прямо в объявлении. Тогда при создании структуры это поле можно опустить. Это удобный способ задавать конфигурации, не перечисляя всё каждый раз.

Как работает под капотом

В памяти структура — это просто её поля, уложенные подряд, как в C. По умолчанию Zig может переупорядочить поля для лучшего выравнивания, но если нужна точная C-совместимая раскладка, используют extern struct или packed struct. Методы не хранятся в экземпляре — это обычные функции, поэтому структура занимает ровно столько, сколько её данные.

Частые ошибки

Первая — забыть точку перед именем поля: пишут x = 3 вместо .x = 3. Вторая — пропустить поле без умолчания и получить ошибку компиляции. Третья — ждать «скрытого this»: в Zig self — обычный явный параметр, и его тип вы указываете сами.

Итог

  • struct { ... } группирует поля; тип присваивают const.
  • Поля инициализируют по имени: .{ .x = 3, .y = 4 }.
  • Методы — функции внутри структуры с явным первым параметром self.
  • Поля могут иметь значения по умолчанию, которые тогда можно опускать.
Проверьте себя
1. Чем является вызов метода p.method() в Zig?
AОсобой конструкцией с скрытым this
BСахаром для Type.method(p) с явным первым параметром self
CВызовом через указатель на таблицу методов
DВиртуальным вызовом
2. Что произойдёт, если при создании структуры не задать поле без значения по умолчанию?
AПоле получит ноль
BОшибка компиляции — нужно заполнить все поля
CПоле останется undefined
DСтруктура не создастся в рантайме