Zig: язык без скрытой магии

Zig: язык без скрытой магии

В 2023 году Stack Overflow назвал Zig самым высокооплачиваемым языком программирования в мире: медиана — $103 000 в год. Выше Rust, выше Go, выше Scala. Через год, в опросе 2024-го, он немного откатился до $75 000, но по-прежнему обогнал C++, JavaScript и SQL. Для языка, на котором пишут меньше процента разработчиков, это впечатляющий сигнал: спрос на системных программистов с Zig растёт быстрее, чем рынок успевает их воспитать.

Но дело не только в деньгах. Bun — альтернатива Node.js, которая запускает JavaScript быстрее всех — написан на Zig. TigerBeetle — финансовая база данных для критически важных систем, где потеря транзакции означает потерю денег — написана на Zig. Ghostty — терминал от Митчелла Хашимото, создателя Terraform, — написан на Zig. Uber использует zig cc для кросс-компиляции Go-монорепозитория на сотни тысяч строк. Язык, которому нет и десяти лет, уже стоит в боевой инфраструктуре компаний, где цена ошибки измеряется миллионами.

Давайте разберёмся, что за ним стоит, почему он появился, чем принципиально отличается от Rust и C++ и стоит ли тратить время на изучение.

Как появился Zig

В 2015 году Эндрю Келли работал над Genesis DAW — аудиостудией, где слышен буквально каждый лишний такт процессора. Задержка в обработке звука — это не лагающий интерфейс, а слышимый щелчок в наушниках. Проект был на C, и Келли устал. Не от сложности задачи, от сложности инструмента.

«В C слишком много способов случайно создать баг», — объяснял он позже. Неинициализированная память, которая иногда работает, а иногда нет. Неявное приведение типов, которое молча обрезает данные. Препроцессор, который превращает код в нечитаемую кашу из #ifdef. Неопределённое поведение, которое делает корректную программу некорректной при смене компилятора или уровня оптимизации. Каждый из этих дефектов по отдельности терпим, но вместе они создают среду, где случайные баги — норма, а не исключение.

Келли начал проектировать язык, который сохранит скорость и контроль C, но уберёт случайную сложность. Не добавит новую сложность (как C++ с его шаблонами, SFINAE и перегрузкой операторов), а именно уберёт лишнее.

Хронология:

  • 2015 — первый коммит. Келли проектирует Zig параллельно с работой над Genesis DAW.
  • 2017 — первые публичные доклады. Келли объясняет мотивацию: «Zig — это C, в котором исправлены ошибки дизайна, а не C, в который добавлены возможности».
  • 2018 — Келли уволился из OkCupid, чтобы работать над Zig полный день. Рискованный шаг для языка без финансирования и с несколькими сотнями пользователей.
  • 2020 — появилась Zig Software Foundation, некоммерческая организация, которая координирует разработку и принимает гранты. Это дало проекту устойчивость: разработчики получили зарплаты, появился бюджет на инфраструктуру.
  • 2023 — Zig попадает в опрос Stack Overflow как самый высокооплачиваемый язык. Bun и TigerBeetle приносят реальную известность.
  • 2025 — миграция на Codeberg (уход с GitHub), грант $512 000 от Synadia и TigerBeetle.
  • 2026 — активная работа над компилятором, новой подсистемой std.Io.Evented, продвижение к стабильному релизу.

За десять лет Zig прошёл путь от побочного проекта одного разочарованного C-программиста до языка с некоммерческим фондом, корпоративными спонсорами и промышленными пользователями масштаба Uber.

Простая философия: никаких сюрпризов

Главный принцип Zig можно уместить в две формулы: никакого скрытого потока управления и никаких скрытых аллокаций. Звучит просто, но последствия для дизайна языка — радикальные.

Явные аллокаторы вместо глобального malloc

В C вы вызываете malloc и надеетесь, что кто-нибудь потом вызовет free. В C++ вы оборачиваете это в unique_ptr или shared_ptr и надеетесь, что никто не вытащит голый указатель. В обоих случаях аллокация скрыта: вы не видите в сигнатуре функции, что она выделяет память.

В Zig каждая функция, которой нужна динамическая память, получает аллокатор как явный параметр:

// C: кто аллоцирует? Когда освобождать? Непонятно из сигнатуры.
// char* read_file(const char* path);

// Zig: аллокатор передан явно — вы контролируете, откуда берётся память.
fn readFile(allocator: std.mem.Allocator, path: []const u8) ![]u8 {
    const file = try std.fs.cwd().openFile(path, .{});
    defer file.close();
    return try file.readToEndAlloc(allocator, std.math.maxInt(usize));
}

Это не просто стиль кодирования. Это архитектурное решение с практическими следствиями. Во-первых, код становится тестируемым: в тестах можно подставить std.testing.allocator, который детектирует утечки памяти и двойное освобождение. Во-вторых, вы можете выбрать стратегию аллокации под задачу: page_allocator для больших блоков, ArenaAllocator для «аллоцировал всё, потом освободил одним махом», FixedBufferAllocator для работы без кучи вовсе.

Ошибки как значения

Zig не использует исключения. Вместо этого функция возвращает error union — тип, который содержит либо результат, либо ошибку:

fn parsePort(str: []const u8) !u16 {
    // std.fmt.parseInt возвращает ошибку, если строка — не число.
    // `try` пробрасывает ошибку наверх, если она произошла.
    return std.fmt.parseInt(u16, str, 10);
}

pub fn main() void {
    const port = parsePort("8080") catch |err| {
        std.debug.print("Неверный порт: {}\n", .{err});
        return;
    };
    std.debug.print("Порт: {}\n", .{port});
}

Это похоже на Go, но реализовано строже. В Go можно проигнорировать ошибку — просто не проверить второй возвращаемый аргумент. В Zig компилятор не даст вам «забыть» ошибку: если функция возвращает !T, вызывающий код обязан обработать ошибку через try, catch или явный _ = . Это похоже на Rust с его Result<T, E>, но синтаксически легче — нет необходимости в .unwrap(), .map(), .and_then() и прочих комбинаторах.

defer и errdefer вместо скрытых деструкторов

В C++ ресурсы освобождаются через деструкторы — это принцип RAII: захватил ресурс при создании объекта, освободил при его разрушении. Элегантно, но непрозрачно: деструктор вызывается неявно, когда объект выходит из области видимости, и вы не видите этого в коде. Получается магия. И в сложных случаях этот неявный порядок разрушения объектов может стать источником багов.

В Zig код очистки пишется рядом с созданием ресурса:

fn processFile(path: []const u8) !void {
    const file = try std.fs.cwd().openFile(path, .{});
    defer file.close(); // Закроется при выходе из функции — в любом случае.

    var buffer: [4096]u8 = undefined;
    const bytes_read = try file.read(&buffer);
    // ... работа с данными ...
}

errdefer — ещё мощнее. Он срабатывает только при ошибке, что позволяет корректно откатывать промежуточные действия:

fn initSystem(allocator: std.mem.Allocator) !*System {
    const sys = try allocator.create(System);
    errdefer allocator.destroy(sys); // Освободить, если дальше что-то упадёт.

    sys.db = try connectDB();
    errdefer sys.db.close(); // Закрыть БД, если следующий шаг упадёт.

    sys.cache = try initCache(allocator);
    // Если мы дошли сюда — всё успешно, errdefer не сработают.
    return sys;
}

Никаких скрытых вызовов, никаких неявных порядков разрушения — вся очистка на виду, в том порядке, в котором вы её написали.

Ключевые возможности

comptime — один язык вместо двух

Это, пожалуй, самая необычная возможность Zig и то, что отличает его от всех конкурентов. В C есть препроцессор — отдельный текстовый язык, который работает до компиляции и не знает ничего о типах. В C++ есть шаблоны — полные по Тьюрингу, но с синтаксисом, от которого плачут. В Rust есть процедурные макросы — мощные, но требующие отдельного крейта и работы с AST.

В Zig всё это заменяет одна концепция: comptime. Это обычный Zig-код, который выполняется во время компиляции. Не макроязык, не шаблонная магия — тот же синтаксис, те же правила, тот же отладчик.

Пример — обобщённая функция, которая работает с любым числовым типом:

fn max(comptime T: type, a: T, b: T) T {
    return if (a > b) a else b;
}

// Вызов:
const result = max(u32, 10, 20); // T = u32, определяется на этапе компиляции.

Никаких template<typename T>, никаких where T: Ord. Просто функция, которая принимает тип как параметр.

Более мощный пример — генерация таблицы подстановки на этапе компиляции:

const hex_table = comptime blk: {
    var table: [256]u8 = undefined;
    for (0..256) |i| {
        table[i] = if (i >= 'a' and i <= 'f')
            @intCast(i - 'a' + 10)
        else if (i >= 'A' and i <= 'F')
            @intCast(i - 'A' + 10)
        else if (i >= '0' and i <= '9')
            @intCast(i - '0')
        else
            0xFF;
    }
    break :blk table;
};

Эта таблица вычисляется при компиляции и попадает в бинарник как константа. Во время выполнения — ноль вычислений, просто обращение по индексу.

Крошечные бинарники

«Hello world» на Zig весит 9,8 КБ на Linux. На Windows — 4 КБ. Для контекста:

Язык Размер «hello world»
Zig ~10 КБ
C (gcc, static) ~16 КБ
Go ~1,8 МБ
Rust (по умолчанию) ~300 КБ
Rust (stripped, LTO) ~50 КБ

Zig достигает этого за счёт отсутствия скрытой среды выполнения. Нет сборщика мусора, нет встроенного аллокатора, нет глобального состояния стандартной библиотеки, которое инициализируется при старте. Вы платите только за то, что используете.

Для встраиваемых систем и WebAssembly это критично. Когда бинарник уходит по сети или прошивается в микроконтроллер, каждый килобайт на счету.

Кросс-компиляция из коробки

Кросс-компиляция в C/C++ — это отдельный вид страдания. Нужен набор инструментов для целевой платформы, sysroot с правильными заголовками и библиотеками, конфигурация CMake или Makefile, которая знает про все эти пути. На практике люди поднимают Docker-контейнеры или сборочные конвейеры с нативными компиляторами.

В Zig кросс-компиляция — одна команда:

# Собрать для ARM64 Linux, сидя на macOS x86_64:
zig build-exe main.zig -target aarch64-linux-gnu

# Собрать для Windows:
zig build-exe main.zig -target x86_64-windows-msvc

# Собрать для WebAssembly:
zig build-exe main.zig -target wasm32-freestanding

Никаких внешних зависимостей, никакой конфигурации. Zig поставляется со всем необходимым для сборки под 40+ целевых платформ.

Независимость от glibc

Стандартная библиотека C (glibc) — это то, что привязывает бинарник к конкретной версии Linux. Собрали на Ubuntu 24.04 — не работает на CentOS 7. Классическое решение — собирать статически с musl, но это не всегда вариант.

Zig решает проблему иначе. Он умеет делать прямые системные вызовы, обходя glibc целиком. А если glibc всё-таки нужна — можно выбрать конкретную версию:

# Собрать с glibc 2.17 (CentOS 7):
zig build-exe main.zig -target x86_64-linux-gnu.2.17

# Собрать с glibc 2.28 (Debian 10):
zig build-exe main.zig -target x86_64-linux-gnu.2.28

Для инженеров эксплуатации и тех, кто разворачивает сервисы на разношёрстный парк серверов, это избавление от целого класса проблем.

zig cc — прямая замена GCC и Clang

zig cc — это компилятор C/C++, встроенный в Zig. Он совместим с GCC/Clang по флагам и может подставляться вместо них без изменения кода.

Именно так его использует Uber. У компании — Go-монорепозиторий, который нужно собирать для разных архитектур. Go использует cgo для вызова C-кода, а cgo требует C-компилятор. Вместо зоопарка кросс-компиляторов инженеры Uber подставляют zig cc:

CC="zig cc -target aarch64-linux-gnu" go build ./...

Одна строка — и Go-проект с C-зависимостями собирается для ARM64 на x86_64-машине.

Совместимость с C без накладных расходов

В Rust для вызова C-функции нужен extern "C" блок, unsafe обёртка, и часто — кодогенератор (bindgen), который парсит заголовки. В Go — cgo, который замедляет сборку и добавляет накладные расходы на вызов.

В Zig достаточно одной строки:

const c = @cImport({
    @cInclude("sqlite3.h");
});

pub fn main() !void {
    var db: ?*c.sqlite3 = null;
    const rc = c.sqlite3_open(":memory:", &db);
    if (rc != c.SQLITE_OK) {
        return error.SqliteOpenFailed;
    }
    defer _ = c.sqlite3_close(db);
    // ... работа с SQLite ...
}

@cImport транслирует C-заголовки напрямую на этапе компиляции. Никаких обёрток, никаких кодогенераторов, никаких накладных расходов на вызов — вызов C-функции из Zig стоит ровно столько же, сколько вызов из C.

Это делает Zig уникальным мостом: можно постепенно переписывать C-проект на Zig, файл за файлом, без промежуточных слоёв.

Кто уже использует Zig

Bun

Bun — среда выполнения JavaScript, альтернатива Node.js и Deno. Джарред Самнер начал проект в 2022 году и выбрал Zig, потому что тот давал контроль над памятью на уровне C, но с современной эргономикой — объединения ошибок, defer, comptime. Bun стал одним из самых быстрорастущих проектов с открытым кодом в 2023 году: 70 000 звёзд на GitHub, миллионы скачиваний.

Ключевой аргумент Самнера: «Zig позволяет писать код, который работает так же быстро, как C, но его реально можно поддерживать командой». Bun использует comptime для генерации парсеров и @cImport для интеграции с JavaScriptCore (движок Safari).

TigerBeetle

TigerBeetle — финансовая база данных, спроектированная для критически важных систем. Это не «ещё одна NoSQL» — это БД, которая гарантирует корректность финансовых транзакций при аппаратных сбоях, сетевых разрывах и конкурентном доступе.

Команда TigerBeetle не просто использует Zig — они инвестируют в его развитие, перечисляя деньги в Zig Software Foundation. «Zig даёт нам контроль, который нужен для финансовых систем, без когнитивной нагрузки C++», — объяснял Джоран Грегор Дирк, создатель проекта. «В C++ нам бы пришлось бороться со скрытыми аллокациями и неявными вызовами конструкторов. В Zig мы точно знаем, что происходит в каждой строке».

Особенно важен для TigerBeetle детерминизм — способность точно воспроизвести поведение системы. Явные аллокаторы Zig и отсутствие скрытого потока управления делают код детерминированным по конструкции.

Ghostty

Ghostty — терминал от Митчелла Хашимото, создателя Terraform, Vagrant, Consul и Packer. Хашимото — один из самых известных разработчиков инфраструктурного софта в мире, и его выбор языка для личного проекта — сигнал для индустрии.

Хашимото выбрал Zig после оценки нескольких языков, включая Rust. Он публично рассказывал о своём опыте: «Zig позволяет мне думать о проблеме, а не о языке. Я не воюю с анализатором заимствований, я пишу код, который делает то, что мне нужно». Ghostty использует Zig для рендеринга терминала через GPU, парсинга escape-последовательностей и управления памятью оконной системы.

Uber

Uber использует zig cc для кросс-компиляции Go-кода. Инженеры компании рассказывали на конференциях, как замена инструментария сборки позволила собирать бинарники для ARM64-серверов на x86_64-машинах без Docker-контейнеров и виртуалок. zig cc поддерживает полную кросс-компиляцию, гермитичность сборки, выбор версии glibc и кэширование — всё в одном инструменте.

Показательно, что Uber использует именно zig cc, а не сам язык Zig. Это демонстрирует ширину проекта: Zig полезен даже тем, кто не пишет на нём ни строки.

Mach

Mach — игровой движок, построенный с нуля на Zig. Проект использует comptime для генерации GPU-конвейеров на этапе компиляции: описание шейдеров, буферов и привязок проверяется компилятором, а не падает во время выполнения с невнятной ошибкой драйвера. Mach показывает, что Zig подходит не только для серверного и инфраструктурного кода, но и для графики и разработки игр.

Zig vs Rust vs C vs C++

Таблица сравнения

Zig Rust C C++
Управление памятью явные аллокаторы анализатор заимствований ручное (malloc/free) RAII + умные указатели
Обработка ошибок объединения ошибок Result<T, E> коды возврата исключения
Метапрограммирование comptime процедурные макросы препроцессор шаблоны
Скрытый поток управления нет частично (Drop, Deref) нет да (конструкторы, перегрузка)
Кросс-компиляция встроена через rustup target внешние инструменты внешние инструменты
Совместимость с C нативная (@cImport) через FFI (unsafe) частичная
Защита от null опционалы (?T) Option<T> нет std::optional
Многопоточность async/await (в разработке) async/await, tokio pthreads std::thread, std::async
Пакетный менеджер встроен в систему сборки cargo нет (CMake, Conan) нет (CMake, vcpkg)
Размер «hello world» ~10 КБ ~300 КБ ~16 КБ ~16 КБ
Кривая обучения 2–3 мес. 5–6 мес. 1–2 мес. 6–12 мес.

Философские различия

Zig и Rust решают одну проблему — «как писать системный код без ошибок памяти», но радикально разными способами.

Rust ставит на анализатор заимствований (borrow checker) — встроенный в компилятор механизм, который отслеживает, кто владеет каждым куском данных и кому разрешено его читать или менять. Если анализатор не может доказать, что обращение к памяти безопасно, программа просто не скомпилируется. Это мощная гарантия: компилятор математически доказывает, что программа не содержит гонок данных, использования освобождённой памяти и висячих указателей. За это приходится платить: система времён жизни требует аннотаций ('a, 'static), владение иногда приходится перестраивать ради компилятора, а не ради логики, и кривая обучения круче, чем у любого другого распространённого языка.

Zig идёт другим путём: язык не запрещает опасные вещи, но делает их видимыми. Вместо анализатора заимствований — явные аллокаторы и defer. Вместо unsafe-блоков прозрачность каждой операции. Ошибиться можно, но для этого нужно сознательно проигнорировать defer, и это будет видно в коде.

Метафора: Rust — это автомобиль, который не даёт вам повернуть руль в стену. Zig — это автомобиль с прозрачными стенами, где вы видите каждый механизм и сами решаете, куда ехать.

Кривая обучения

Практики оценивают кривую обучения так:

  • C: 1–2 месяца до продуктивности. Язык маленький, но ловушек много. Вы будете годами учиться на своих ошибках.
  • Zig: 2–3 месяца. Синтаксис минималистичный, концепции (аллокаторы, объединения ошибок, comptime) непривычные, но каждая — ровно одна идея, без вариаций и без магии.
  • Rust: 5–6 месяцев. Анализатор заимствований требует перестройки мышления. Времена жизни, типажи, макросы, асинхронность — каждая тема довольно сложная.
  • C++: 6–12 месяцев до уверенного владения. Язык огромный, идиом множество, стандартов — десять, и каждый добавляет новый слой сложности.

Где кто лучше

Zig лучше, когда:

  • нужна прозрачность и предсказуемость — драйверы, встраиваемые системы, сетевые серверы;
  • нужна кросс-компиляция без боли;
  • вы работаете с C-кодом и хотите постепенно его заменить;
  • размер бинарника критичен (IoT, WebAssembly);
  • нужно детерминированное поведение (финансы, реальное время).

Rust лучше, когда:

  • корректность важнее прозрачности — криптография, браузерные движки;
  • многопоточность с разделяемым состоянием — анализатор заимствований ловит гонки данных на этапе компиляции;
  • нужна зрелая экосистема — crates.io, документация, инструментарий;
  • проект долгоживущий и командный — строгость Rust окупается на длинной дистанции.

C лучше, когда:

  • нужна максимальная портируемость — ядра ОС, прошивки;
  • существующая кодовая база на C, и переписывать нет смысла;
  • вы точно знаете, что делаете, и вам не нужен «страховочный пояс».

C++ лучше, когда:

  • нужна зрелая экосистема для конкретной области — разработка игр (Unreal Engine), САПР, высокопроизводительные вычисления;
  • команда уже владеет C++ и переход нецелесообразен.

Зарплаты и рынок

Цифры из опросов Stack Overflow впечатляют, но заслуживают разбора:

  • Stack Overflow 2023: $103 000 медиана — первое место среди всех языков. Выше Erlang ($99 000), Rust ($87 000) и Go ($92 000).
  • Stack Overflow 2024: $75 000 — снижение, но по-прежнему выше C++ ($66 000), JavaScript ($63 000) и SQL ($60 000).

Причина высоких зарплат — не в самом языке, а в профиле разработчиков. Zig используют 0,83 % респондентов опроса. Это не джуниоры, которые освоили язык на курсе. Это опытные системные программисты, которые осознанно выбрали нишевый инструмент. Их зарплаты высоки не потому, что они пишут на Zig, а потому, что они решают задачи, за которые хорошо платят: инфраструктура, базы данных, среды выполнения, компиляторы.

Нюансы стоит проговорить честно:

  • Малая выборка делает медиану волатильной. Скачок со $103 000 до $75 000 за год — это не падение зарплат, а статистический шум от нескольких сотен респондентов.
  • Вакансий «Zig-разработчик» на рынке мало. Большинство позиций формулируются как «системный программист» или «инженер инфраструктуры», и Zig — лишь одна из строчек в списке навыков, а не основное требование.
  • Корреляция — не причинность. Высокие зарплаты коррелируют с Zig, но не вызваны им. Те же люди на Rust или C++ получали бы сравнимые деньги.

Тем не менее тренд настоящий. Компании, которым нужен системный софт, особенно с кросс-компиляцией, совместимостью с C и детерминизмом, всё чаще обращают внимание на Zig. А чем меньше специалистов и чем выше спрос, тем выше зарплата. Это базовая экономика.

Что нужно знать перед стартом

Zig — язык в активной разработке. Версия 1.0 ещё не вышла; ожидается ориентировочно в 2026–2027 году. Прежде чем инвестировать время, стоит понимать практические последствия.

Обратно несовместимые изменения между версиями. Код, написанный для 0.13, может не собраться на 0.14. Стандартная библиотека активно рефакторится, API меняются. Документация ведётся отдельно для стабильной и основной ветки, так что иногда примеры из статей двухлетней давности просто не работают. Если вы привыкли к стабильности Go или Rust, здесь всё иначе. Версия Zig должна быть частью конфигурации проекта, и при обновлении нужно быть готовым к правкам.

Экосистема растёт, но пока невелика. Пакетный менеджер встроен в систему сборки, библиотек становится больше, но до crates.io (Rust) или pkg.go.dev (Go) ещё далеко. Многие задачи, для которых в других языках есть готовая библиотека, в Zig придётся решать через совместимость с C или писать самостоятельно. Это одновременно минус (больше работы) и плюс (меньше чужих абстракций, больше контроля).

Сообщество дружелюбное и активное. Discord, форумы, Ziggit — на вопросы отвечают быстро, часто с примерами кода. Эндрю Келли лично участвует в обсуждениях. Для языка до версии 1.0 с маленькой базой пользователей качество сообщества необычно высокое.

Инструментарий развивается. ZLS (Zig Language Server) работает с VS Code, Neovim и другими редакторами. Отладка через GDB/LLDB поддерживается. zig fmt форматирует код единообразно. Но поддержка в редакторах пока не на уровне Rust (rust-analyzer) или Go (gopls) — автодополнение иногда ломается, рефакторинг ограничен.

Если вам нужен язык для боевого применения прямо сейчас — оцените риски. Bun, TigerBeetle и Ghostty показывают, что это возможно, но каждая из этих команд имеет ресурсы для работы с нестабильным языком. Если хотите войти в системное программирование и расти вместе с инструментом — момент подходящий: сообщество маленькое, участники разработки заметны, а опыт с Zig до версии 1.0 ценится.

Как начать

Установка

# macOS
brew install zig

# Linux (snap)
snap install zig --classic --beta

# Или скачать бинарник с ziglang.org/download
# Распаковать и добавить в PATH — готово.

Первый проект

mkdir hello-zig && cd hello-zig
zig init
zig build run

zig init создаёт проект с build.zig, src/main.zig и структурой, готовой к работе.

«Hello world»

const std = @import("std");

pub fn main() void {
    std.debug.print("Hello, {s}!\n", .{"Zig"});
}

Сохраните в файл и запустите zig run hello.zig. Компиляция и запуск происходят за доли секунды.

Чуть сложнее — чтение аргументов командной строки

const std = @import("std");

pub fn main() !void {
    var args = std.process.args();
    _ = args.next(); // Пропустить имя программы.

    const name = args.next() orelse {
        std.debug.print("Использование: greet <имя>\n", .{});
        return;
    };

    const stdout = std.io.getStdOut().writer();
    try stdout.print("Привет, {s}!\n", .{name});
}

Обратите внимание: args.next() возвращает ?[]const u8 — опционал. Если аргумента нет, вы получаете null, а не падение с segfault. Это Zig: ошибки и отсутствие данных всегда явные.

Ресурсы для изучения

  • Zig Language Reference — основной источник истины, ведётся для стабильной и основной ветки;
  • zig.guide — структурированный учебник для людей с опытом программирования, покрывает ошибки, аллокаторы, систему сборки;
  • Ziglings — упражнения в формате «починить сломанную программу», аналог Rustlings;
  • Zig Build System — документация по системе сборки, которая в Zig является частью языка;
  • Introduction to Zig — проектная книга с примерами от HTTP-сервера до кодировщика Base64.

Заключение

Zig — не «убийца C» и не «Rust для ленивых». Это отдельная философия: писать системный код так, чтобы каждая строка была предсказуемой. Без скрытых аллокаций. Без скрытого потока управления. Без магии, которая ломается в три часа ночи, когда все спят, а сервер горит.

Язык ещё молод, экосистема ещё невелика, и 1.0 пока впереди. Но Bun, TigerBeetle, Ghostty и Uber уже сделали свою ставку. Если вас привлекает системное программирование — или если вы устали от сложности C++ и крутой кривой обучения Rust — попробуйте zig init и напишите первый «hello world». Девять килобайт бинарника скажут больше, чем любая статья.

Предыдущий
Наверх