Философия явности: что отличает Zig от C

Разбираем философию языка: почему Zig делает ставку на явность и читаемость.

Явность в Zig — принцип, при котором любое выделение памяти, любой вызов функции и любой поток управления видны прямо в коде, без скрытой работы за кулисами.

Чтобы по-настоящему понять Zig, недостаточно выучить синтаксис — нужно проникнуться его философией. Она кратко сформулирована в zig zen, но главная мысль такая: код читают гораздо чаще, чем пишут, поэтому язык должен оптимизировать чтение, а не экономить нажатия клавиш.

Магия — это долг

В C++ выражение a + b для пользовательских типов может вызвать перегруженный оператор, который под капотом выделяет память, бросает исключение и логирует в файл. Читая код, вы этого не видите. Zig объявляет такую «магию» техническим долгом: чем больше скрытого поведения, тем труднее понять и отладить программу.

Нет перегрузки операторов

В Zig + всегда складывает числа, и точка. Если вам нужно «сложить» две матрицы — вы пишете функцию add(a, b), и в коде явно виден её вызов.

Нет деструкторов

В C++ объект сам освобождает ресурсы в деструкторе — удобно, но невидимо. Zig использует defer: вы пишете освобождение явной строкой, и оно видно в теле функции.

const std = @import("std");

pub fn main() void {
    // defer переносит выполнение строки в конец блока
    defer std.debug.print("3. освобождаем ресурс\n", .{});
    std.debug.print("1. открыли ресурс\n", .{});
    std.debug.print("2. работаем\n", .{});
}

Вывод:

1. открыли ресурс
2. работаем
3. освобождаем ресурс

Один очевидный способ

Дзен Zig гласит: «Только одна очевидная манера делать вещи». В отличие от C++ с его десятком способов инициализировать переменную, Zig стремится к единственному читаемому варианту. Это снижает когнитивную нагрузку в командах.

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

Отсутствие скрытого потока управления — не просто эстетика. Когда нет исключений, компилятор не обязан вставлять код раскрутки стека на каждый вызов функции. Когда нет перегрузки операторов, оптимизатору проще рассуждать о коде. Явность даёт предсказуемую производительность: вы можете на глаз оценить, что и когда выполнится.

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

Программисты из C++ часто пытаются «обернуть» ресурс в тип с автоосвобождением. В Zig идиома другая: создал — тут же написал defer на освобождение. Если вы привыкли к RAII, перестройка мышления займёт время, но взамен вы всегда видите время жизни ресурса.

Итог

  • Zig оптимизирует чтение кода, а не скорость его написания.
  • Нет перегрузки операторов, деструкторов и исключений — меньше скрытой магии.
  • defer делает освобождение ресурсов явным и видимым.
  • Принцип «один очевидный способ» снижает когнитивную нагрузку.
Проверьте себя
1. Почему в Zig нет перегрузки операторов?
AЭто технически невозможно
BЧтобы знак + всегда означал ровно сложение чисел без скрытых вызовов
CЧтобы код было сложнее читать
DИз-за ограничений LLVM
2. Что делает defer в Zig?
AОткладывает компиляцию строки
BПереносит выполнение выражения в конец текущего блока
CСоздаёт новый поток
DУдаляет переменную немедленно