# Глава 1. Безопасность прежде всего

Привет! Готов погрузиться в Zig — мощный и на удивление дружелюбный язык системного программирования? В этой главе мы познакомимся с самыми интересными возможностями Zig. Это как первый глоток того, что делает Zig новым языком на слуху у всех.

Мы начнём с обзора современного состояния системного программирования и объясним, почему свежий язык вроде Zig — именно то, что нужно разработчикам. Рассмотрим типичные «головные боли» при работе с мейнстримными языками, а затем посмотрим, как Zig решает эти проблемы. Пройдёмся по основам: синтаксису, управлению памятью и выдающимся возможностям вроде метапрограммирования на этапе компиляции. Особое внимание уделим философии Zig — избегать ненужной сложности, чтобы в коде было видно ровно то, что происходит.

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

В этой главе мы рассмотрим следующие основные темы:

  • Учимся думать на Zig.
  • Системное программирование по-новому.
  • Поддержка с помощью Zig.
  • Начинается новая эра.

# Учимся думать на Zig

Изучение нового языка программирования — не прогулка по парку, особенно если речь о системном языке вроде Zig. Может показаться, что проблема в мозге: мол, он не приспособлен к такому низкому уровню и техническим деталям.

На самом деле дело не в мозге, а в том, как вы его «кормите». Мозг любит новизну, всегда ищет что-то новое и интересное — так он устроен, чтобы держать вас в тонусе и, буквально, в живых. Рутина, обыденность или скука заставляют его отключаться и переводить такие задачи в фон.

Как мозг решает, что важно? Представьте: вы кодите, полностью погружены в работу, и вдруг компьютер начинает перегреваться, вентиляторы ревут как самолёт. Мозг тут же мобилизуется: нейроны активируются, эмоции зашкаливают, адреналин подскакивает. Так он понимает: происходит что-то важное. Всё ради выживания — а в программировании выживание означает стабильную работу машины и кода. Поверьте, к концу этого пути вы увидите: учить Zig не так сложно, как кажется сейчас.

Давайте сразу проясним: это не тот случай, когда можно «прочитать и повторить», а потом отключиться после второго абзаца. Нет, мы сделаем кое-что революционное: заставим вас думать. Да-да, шокирующе! Будем задавать рефлексивные вопросы (кто не любит немного посомневаться в себе во время учёбы?), добавлять викторины — хотя бы чтобы вы не заснули. А потом, когда покажется, что вы всё поняли, дадим практические упражнения — чтобы вы не просто кивали как болванчик.

Каждая глава — ловко замаскированная ловушка (то есть ступенька), которая опирается на предыдущую. Сложность нарастает, но не волнуйтесь: всё по плану. Вы будете возвращаться к «основам» снова и снова, потому что повторение — мать учения. Кто бы мог подумать?

Начнём с основ. Да, с основ — потому что сначала нужно научиться ползать, прежде чем пытаться бежать. Вы познакомитесь с синтаксисом и возможностями Zig, и, несомненно, будете недоумевать, почему не выбрали более «попсовый» язык. Но не сдавайтесь. Вы будете решать задачи, отвечать на вопросы и выполнять упражнения, которые — хотите верьте, хотите нет — имеют отношение к реальной жизни.

К концу нашего путешествия Zig станет не просто ещё одним языком в вашем арсенале — это будет бензопила для серьёзной работы. Так что пристегнитесь, дорогой друг! Нас ждёт дикая, саркастичная и удивительно эффективная поездка по миру программирования на Zig!

# Системное программирование по-новому

Когда вы погружаетесь в запутанный мир системного программирования, то вскоре натыкаетесь на привычные инструменты. Есть классика — C и C++, эти старые рокеры, которые не хотят уходить на пенсию. Есть хипстеры D и Odin — настолько нишевые, что просто знать об их существовании уже как тайное знание. И, конечно, появляются крутые ребята с Rust и Go, которые хвастаются своими блестящими возможностями и ведут себя так, будто изобрели велосипед.

Но вот в чём загвоздка: несмотря на всё разнообразие, ни один из этих тяжеловесов так и не смог найти идеальный баланс между простотой, прозрачностью и переносимостью. Пока не появился Zig и не показал всем, как надо. Zig не просто целится в золотую середину — он там закрепился и бросает вызов остальным.

# Язык X против языка Y

В этой главе вы встретите сравнения с другими языками программирования, такими как C, Go и Rust. Не волнуйтесь, если вы не знакомы с этими языками, — эти сравнения приведены просто для того, чтобы помочь тем, кто с ними знаком. Они показывают, чем Zig отличается от других языков и какой подход использует. Если какие-то из этих сравнений вам ни о чем не говорят, ничего страшного. Цель состоит в том, чтобы дать вам более широкое представление о языке, но при этом вы получите всю необходимую информацию, чтобы понять, что такое Zig.

# Происхождение Zig — исправляем сломанное

Эндрю Келли устал от бесконечных подводных камней, которые подстерегают вас на пути в языках C и C++. Поэтому он решил создать язык Zig — язык, который не заставляет вас выбирать между современными средствами обеспечения безопасности и низкоуровневым контролем, от которого без ума системные программисты. Zig появился не в результате какого-то академического исследования или желания изобрести велосипед, а был создан по необходимости, чтобы устранить недостатки своих предшественников. Другими словами, он был создан из-за глубокого разочарования автора в недостатках языков C и C++, особенно в их неопределенном поведении, отсутствии гарантий безопасности и сложностях, связанных с поддержкой больших кодовых баз. Как сказал сам Келли: «Я верю, что мы можем сделать лучше».

Но ведь языков уже много! Почему именно Zig должен оказаться в центре внимания? Ответ кроется в философии дизайна: простота, прозрачность и переносимость.

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

Келли также вдохновлялся своим опытом работы с другими языками и инструментами, что позволило ему реализовать функции, о которых мы рассказываем в этой книге.

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

# Недостатки мейнстримных языков

Мейнстримные языки системного программирования при всей своей популярности полны недостатков, которые раздражают разработчиков десятилетиями. Давайте разберём несколько болевых точек и посмотрим, как Zig их устраняет:

  • Сборщик мусора: необходимое зло?
    На первый взгляд, сборка мусора — это мечта любого разработчика. Автоматическое управление памятью, которое избавляет от рутинной работы? Я только за! Но на деле сборка мусора — это как друг, который приходит без приглашения, устраивает беспорядок и оставляет вас разбираться с последствиями. За это удобство приходится расплачиваться ужасными задержками, которые могут превратить плавное взаимодействие с пользователем в кошмар. Конечно, намерения благие, но когда ваше приложение зависает из-за несвоевременной приостановки сборки мусора, благие намерения не помогают.

  • Автоматическое выделение кучи: бомба замедленного действия.
    Ещё есть автоматическое выделение памяти в куче. Всё весело до тех пор, пока система не исчерпает память. Тогда программа становится не просто неэффективной — она вообще непригодна к использованию. Вылеты из-за нехватки памяти слишком часты там, где система сама решает когда выделять кучу. Это как дать ключи от машины тому, кто не умеет водить: поначалу всё может быть хорошо, но рано или поздно случится авария.

  • Сложные процессы сборки: головная боль номер один.
    Поговорим о сборке кода. Если ваш язык превращает сборку из исходников в запутанный клубок скриптов, зависимостей и загадочных инструментов — он уже проиграл. Сложная сборка мгновенно отпугивает большинство разработчиков, которым просто хочется собрать код без PhD по системам сборки. Но многие мейнстримные языки считают сложные процессы сборки обрядом посвящения.

# Решение? Очевидно, Zig

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

  • Нет сборщика мусора — больше контроля.
    Zig полностью отказывается от сборщика мусора: никаких непредсказуемых stop-the-world пауз! Это даёт полный контроль над управлением памятью — критично для системного программирования и приложений с высокими требованиями к производительности. В Zig вы сами решаете когда выделять и освобождать память, это позволяет тонко настраивать производительность там, где важен каждый байт и такт процессора.

  • Нет скрытых выделений памяти.
    В Zig ручное управление памятью не опция по желанию — это стандарт. Язык вообще не выделяет кучу автоматически, нет ключевого слова new или инструкций с неявным выделением памяти во время выполнения. Ещё раз: если вы явно не запросили выделение кучи — его не будет.

Это резко отличается от Go (где скрытые выделения часты из-за автоматического управления горутинами и GC) или даже Rust (где стандартная библиотека часто предполагает наличие кучи). В Zig можно вообще работать без кучи, что идеально для встраиваемых или real-time систем с детерминированным управлением памятью.

Любая стандартная библиотечная функция требующая кучи требует явного Allocator-параметра: решения о памяти всегда принимает разработчик.

Подробнее об этом в Главе 9 «Управление памятью».

Мы увидели, как Zig обходит ловушки мейнстрима. Но что действительно выделяет его среди других? Он берёт лучшее от C (мощь и контроль) и адаптирует для современного разработчика. Давайте разберёмся почему Zig не просто альтернатива C++/Rust/Go/C#, а именно современная альтернатива самому C.

# Современная альтернатива C

Zig — строго типизированный компилируемый язык, он позиционирует себя как современную альтернативу C и даёт силу низкоуровневого программирования при чистом синтаксисе. В основе лежит знакомая структура C-подобных языков (точки с запятой в конце операторов; блоки кода в фигурных скобках). Это делает синтаксис узнаваемым сразу же, при этом появляются возможности для большей безопасности и универсальности современного ПО.

# Не волнуйтесь!

Если код выглядит непривычно или какие-то части пока непонятны — не переживайте! Это только тизер, всё будет разобрано подробно по ходу книги. К финалу вы поймёте каждую строчку и сможете уверенно писать свои программы на Zig! Пока просто расслабьтесь и получайте удовольствие, скоро всё станет ясно!

Посмотрим первый пример кода на Zig:

const std = @import("std");

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

Этот код импортирует стандартную библиотеку, определяет функцию main() и выводит «Hello, World!» на консоль. Простой способ увидеть базовые операции: импорт пакетов, определение функций и вывод текста при ясном синтаксисе.

Вы уже можете задуматься: а вдруг Zig просто улучшенный C? Ответ короткий: нет! Мы увидим дальше, что у него гораздо больше возможностей.

# Простота — фокус на главном

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

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

Языки с мощными макросами или генерацией кода на этапе компиляции могут внести сложность или скрытые баги при небрежном использовании. Простота Go тоже сила языка, но за неё приходится платить гибкостью (особенно в обработке ошибок или управлении памятью).

Подробнее об этом в Главе 6 «Обработка ошибок».

# Нет скрытого потока управления

В Zig действует принцип «что видишь — то и получаешь». Если код выглядит как простая последовательность операций — так оно и есть, никаких сюрпризов вроде скрытых вызовов функций или изменения потока управления без вашего ведома.

Для разминки взгляните на такой код:

var r = x + y.z;
funcA();
funcB();

И попробуйте найти подвох... А подвоха нет! Это красота Zig: код делает ровно то что написано! funcA() затем funcB() без скрытых вызовов или неожиданностей (в отличие от перегрузки операторов C++). Такая предсказуемость освежает код, его легче читать и понимать логику выполнения.

В Rust/Go есть свои механизмы абстракции (макросы Rust / горутины Go), иногда они могут скрывать реальный поток выполнения программы.

Подробнее об этом в Главе 4 «Поток управления».

# Выполнение кода на этапе компиляции

Одна из выдающихся возможностей Zig — compile-time execution (comptime): возможность запускать код во время компиляции! Это позволяет генерировать/манипулировать кодом динамически ещё до запуска программы. Проверять ограничения или оптимизировать производительность заранее!

Comptime даёт поддержку дженериков (generics), можно писать гибкий переиспользуемый код при строгой типобезопасности! Но этим дело не ограничивается, метапрограммирование во время компиляции позволяет выполнять сложные вычисления ещё до запуска программы!

Если интересно узнать больше о магии comptime — загляните в Главу 12 «Продвинутые темы».

# Инструментарий «из коробки»

Инструментарий Zig создан максимально простым: скачиваете один статически собранный бинарник со всем необходимым внутри!

Zig работает сразу на Linux/Windows/macOS, поддерживает совместимость командной строки GCC/Clang для интеграции с существующими проектами/кодовыми базами (Go тоже славится простой системой инструментов).

Но если Go хорош простотой сборки простых проектов, то у Zig преимущество проявляется именно при сложных сценариях сборки (кросс-компиляция/прямая интеграция C/C++).

Тестирование тоже максимально простое: пишете тесты прямо внутри кода, запускаете командой zig test!

Подробнее о тестировании в Главе 7 «Тестирование вашего кода на Zig».

# Больше чем просто язык

Хотя мы начали знакомство с самим языком, легко подумать что это «ещё один язык». Но это только поверхностное суждение. На самом деле Zig больше чем язык программирования, это ещё и мощная система сборки ПО!

# Почему у Zig своя система сборки?

Традиционные системы сборки часто сложны для освоения (нужно собирать цепочки инструментов/скриптов). У Zig система сборки встроена прямо в язык! Всё делается через понятный синтаксис самого языка без лишних инструментов!

# Единый подход

Система сборки у Zig интегрирована глубоко внутрь языка (это не отдельный плагин/скрипт). Всё пишется прямо на самом языке вплоть до деплоя готового продукта!

Что умеет система сборки?

  • Кросс-компиляция: хотите собрать проект сразу под несколько платформ? Система сборки поддерживает Linux/Windows/macOS/экзотические платформы без изменений кода!
  • Конфигурация проектов: забудьте про сложные скрипты cmake/make/powershell/autoconf! Всё настраивается простым кодом через файл build.zig!
  • Автоматизация задач: генерация кода/тесты/упаковка приложения выполняются прямо внутри системы сборки!

# Кросс-компиляция стала проще

Zig облегчает написание переносимых библиотек благодаря полной совместимости с C ABI (можно интегрировать существующий C-код либо использовать библиотеки из других языков).

Система сборки делает кросс-компиляцию максимально простой через файл build.zig без изменений исходников!

Представьте мир без cmake/make/powershell... С помощью нескольких строк build.zig можно настроить сборку под любую платформу!

Всё прозрачно без необходимости учить отдельный DSL для описания сборки проекта!

# Поддержка с помощью Zig

Один из основных принципов проекта Zig — поддержка с помощью Zig. Но что это значит на самом деле? Для наглядности давайте сравним его с двумя другими языками, которые придерживаются прогрессивного подхода, а не требуют масштабных радикальных изменений: Kotlin и Carbon.

# Kotlin и Carbon

Разработанный компанией JetBrains, Kotlin представляет собой статически типизированный язык программирования, который работает на виртуальной машине Java (JVM) и также может быть скомпилирован в JavaScript или машинный код. Kotlin разработан таким образом, чтобы быть полностью совместимым с Java, что делает его популярным выбором для разработки Android и корпоративных приложений.

Carbon — это язык программирования, разрабатываемый компанией Google в качестве потенциального преемника C++. Он призван устранить ограничения C++, сохранив при этом производительность и контроль над низкоуровневыми системными ресурсами.

В Carbon реализованы современные языковые возможности, повышающие продуктивность разработчиков и безопасность кода.

Например, Kotlin — это эталон совместимости. Он легко интегрируется с существующим кодом на Java, позволяя разработчикам внедрять его в уже существующие проекты, не переделывая все с нуля. Kotlin призван упростить жизнь разработчиков, предлагая такие функции, как защита от нулевых ссылок, лаконичный синтаксис и корутины для асинхронного программирования, при этом оставаясь полностью совместимым с обширной экосистемой Java.

Kotlin особенно привлекателен тем, что его можно осваивать постепенно: разработчики могут начать с малого, конвертируя по одному файлу за раз, и сразу же ощутить преимущества без необходимости длительного обучения.

Аналогичным образом Carbon — это амбициозный ответ Google на устаревший C++. Carbon, задуманный как потенциальный преемник, не требует полной замены всей кодовой базы на C++. Вместо этого он создан для того, чтобы работать в связке с C++, позволяя разработчикам постепенно переходить на Carbon, используя существующий код на C++ и инструменты, в которые они уже вложили средства. Carbon чтит прошлое, но смотрит в будущее, обеспечивая плавный переход для разработчиков, глубоко погруженных в мир C++.

Zig следует по тому же пути постепенной интеграции. Речь идет не о том, чтобы переписать все с нуля, а о том, чтобы развивать свои проекты с минимальными потрясениями. Zig легко интегрируется с кодом на C и C++, позволяя поддерживать и улучшать существующие системы, постепенно внедряя современные возможности Zig. Такая стратегия гарантирует, что вы сможете улучшать и поддерживать свою кодовую базу без рисков и затрат, связанных с масштабным переписыванием кода. Как и в случае с Kotlin и Carbon, Zig сохраняет уже созданную вами основу, предлагая более перспективный путь развития.

Учитывая это, давайте рассмотрим, как простая система сборки Zig позволяет без труда поддерживать и улучшать кодовые базы на C и C++, легко интегрируя современные функции.

# Интероперабельность

Одна из самых сложных задач при поддержке проектов на C/C++ — работа с системой сборки, представляющей собой лабиринт из конфигурационных файлов и зависимостей, которых со временем становится все больше.

Zig предлагает решение этой проблемы с помощью zig build — инструмента, призванного заменить традиционные системы сборки и упростить весь процесс сборки и поддержки ваших проектов.

Хотя мы рассмотрим систему сборки в Главе 11 «Сборка», позвольте мне вкратце рассказать о ее особенностях.

Одной из отличительных особенностей системы сборки Zig является ее простота. Вы определяете процесс сборки в файле build.zig, используя возможности языка Zig для управления всеми аспектами сборки. Такой подход обеспечивает гибкость, при этом все остается простым и понятным.

Создав файл build.zig, вы сможете компилировать свой проект на всех платформах, не прибегая к помощи внешних инструментов, таких как Xcode, MSVC, или даже базовых инструментов сборки, таких как cmake, make, powershell или autoconf. Звучит неплохо, правда?

Это не просто звучит хорошо, это уже стало реальностью. С помощью одного файла build.zig вы можете компилировать свой проект для всех платформ, не прибегая к помощи внешних инструментов, таких как Xcode, или даже к базовым инструментам для сборки.

Хватит слов. Ниже приведен базовый пример того, как выглядит файл build.zig. Не пытайтесь разобраться во всех его аспектах с первого взгляда:

const std = @import("std");
pub fn build(b:*std.Build)void{
    const exe=b.addExecutable(.{
        .name="main",
        .root_source_file=b.path("main.zig"),
        .target=b.host,
    });
    b.installArtifact(exe);
}

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

Как вы, наверное, заметили, в наших фрагментах кода постоянно встречается пакет std. Это не случайно, стандартная библиотека Zig является важнейшей частью языка и играет ключевую роль в разработке. Она предоставляет широкий набор инструментов и утилит, которые упрощают все — от тестирования до решения стандартных задач программирования. Сейчас мы лишь вкратце коснемся этой темы, но будьте уверены, что в Главе 10 «Стандартная библиотека» мы подробно рассмотрим стандартную библиотеку Zig.

Там вы получите полное представление о том, как std помогает писать программы на Zig.

# Почему бы просто не переписать код на Rust?

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

Отказ от старого кода — это не просто потеря самого кода, но и потенциальная потеря многих лет работы над исправлением ошибок, оптимизацией и адаптацией к реальным условиям, которые сделали программное обеспечение надежным. Мнение о том, что новый код по определению лучше, ошибочно. Существующий код уже протестирован и проверен в различных условиях, а разработка с нуля может привести к возвращению старых проблем и появлению новых.

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

Кроме того, сообщество разработчиков ПО с открытым исходным кодом невероятно разнообразно, поэтому ожидать повсеместного внедрения одного языка программирования нереалистично. Чтобы по-настоящему усовершенствовать нашу критически важную программную инфраструктуру, мы должны сосредоточиться на улучшении среды программирования при разработке систем, а не просто менять одни проблемы на другие.

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

Эта стратегия более распространена в сообществе разработчиков на языке Rust. О! Чуть не забыл упомянуть: Rust не компилирует код на C. Так что переписывание кода — не самый прогрессивный подход, верно? ПРАВДА?

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

Zig включает в себя собственный набор библиотек для облегчения кросс-компиляции и предоставляет такие команды, как zig cc и zig c++, которые могут заменить Clang. Такая интеграция позволяет разработчикам использовать современные возможности Zig, не выходя за рамки устоявшейся экосистемы C/C++.

В рамках проекта Zig даже разрабатывается собственный компоновщик zld, который со временем заменит lld, что еще больше снизит зависимость от внешних инструментов, таких как LLVM.

Чтобы лучше понять, в чем преимущества Zig перед C, обязательно прочтите Главу 12 «Продвинутые темы», где мы подробно рассмотрим эту мощную функцию. Там вы узнаете, как Zig делает работу с кодом на C не просто возможной, а по-настоящему простой.

# Слишком хороша, чтобы ее игнорировать

Система Zig build непреднамеренно решает проблемы cgo, упрощая перекрестную компиляцию и управление зависимостями. В отличие от cgo, которая требует сложных конфигураций для каждой целевой платформы, Zig легко справляется с перекрестной компиляцией, не требуя внешних зависимостей.

Такая согласованность устраняет проблемы, связанные с конкретной платформой, упрощая и повышая надежность интеграции кода на C/C++ в проекты на Go.

# CGO

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

Однако использование CGO усложняет кросс-компиляцию и управление зависимостями, часто требуя дополнительной настройки для обеспечения совместимости на разных платформах.

Сборка из исходного кода в Zig не вызывает затруднений, что упрощает интеграцию в рабочие процессы разработки.

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

Zig предлагает несколько режимов релиза оптимизирующих ваш код под разные сценарии использования:

  • Debug режим подходит для разработки, содержит проверки безопасности, пропускает оптимизации, облегчает поиск багов и понимание поведения программы;
  • ReleaseSafe баланс между производительностью надёжностью, оптимизирует код сохраняя проверки безопасности;
  • ReleaseFast максимальная скорость, удаляет большинство проверок безопасности ради максимальной производительности;
  • ReleaseSmall минимальный размер бинарного файла, подходит для встраиваемых систем где важен каждый байт.

Каждый из этих режимов позволяет гибко подстраиваться под конкретные потребности вашего проекта, гарантируя, что вы всегда будете использовать подходящий инструмент для решения конкретной задачи. Мы подробно рассмотрим каждый из этих режимов выпуска в Главе 11 «Сборка», где вы узнаете, как максимально эффективно использовать систему сборки Zig.

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

# Сравнения языков

По мере продвижения по книге вы заметите, что сравнения с другими языками постепенно уходят на второй план. Это сделано намеренно. Хотя такие отсылки в начале помогают обозначить контекст и показать, чем Zig отличается или в чём превосходит другие решения, основной акцент здесь — на освоении самого Zig. Чем глубже мы погружаемся, тем больше внимания уделяется исключительно Zig: его возможностям, сильным сторонам и уникальному подходу к системному программированию. Такой подход позволит вам полностью погрузиться в то, что делает Zig особенным, без отвлечения на постоянные сравнения.

# Начинается новая эра

Системное программирование слишком долго буксовало, увязнув в сложностях C/C++. Но так быть не должно. Проект Zig предлагает свежий взгляд, делая системное программирование более доступным, практичным и эффективным. Благодаря мощному компилятору, гибкой системе сборки, грядущему пакетному менеджеру и простому языку Zig способен вдохнуть новую жизнь в искусство низкоуровневого программирования.

К счастью, вы готовитесь стать частью этих перемен. И между нами: сейчас — идеальное время, чтобы погрузиться в Zig. Независимо от того, вносите ли вы вклад в проекты с открытым исходным кодом, изучаете язык или просто исследуете его возможности, Zig предлагает инструменты и поддержку сообщества, необходимые для успеха. Двигаясь вперёд, Zig не только помогает поддерживать наследие прошлого, но и строит будущее системного программирования.

# Безопасность

Безопасность часто преподносится как главный козырь новых языков программирования, и неудивительно, что эта тема так популярна. Вы наверняка не раз встречали фразу «Rust — более безопасный язык», и в этом есть доля правды. Однако важно разобраться, что на самом деле стоит за словом «безопасность». Дело не только в защите от утечек памяти — этот термин часто используют слишком широко.

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

Так что да, безопасность — это здорово, но Zig играет в другую игру. Его цель — не только защитить от ошибок с памятью, но и сделать код максимально простым, надёжным и предсказуемым. Никаких трюков и сюрпризов — только честное поведение.

Если вдруг засомневаетесь, повесьте себе напоминание: «Безопасность памяти — лишь один из столпов корректности ПО».

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

Кроме того, Zig не просто рекомендует обрабатывать ошибки или отсутствие данных — он практически заставляет это делать. Забудьте про неопределённое поведение в стиле C, Zig пресекает такие попытки на корню.

А ещё есть comptime — возможность выполнять код на этапе компиляции. Это как если бы Zig говорил: «Давай-ка найдём ошибки ещё до запуска программы!». Вы можете проверять и генерировать код во время компиляции, так что к моменту запуска ваша программа уже прошла все проверки. В то время как C спокойно позволяет вам спотыкаться о runtime-ошибки, будто на дворе 1990 год.

Zig заботится даже о расположении данных в памяти: с помощью переупорядочивания полей и упаковки структур вы можете делать свои структуры компактными и эффективными, не опасаясь проблем с выравниванием. И, конечно, вишенка на торте: по умолчанию указатели не могут быть нулевыми. В C указатель может быть NULL, потому что кто же не любит хороший segmentation fault? Но в Zig NULL возможен только если вы явно этого захотите. Это как если бы Zig говорил: «Хочешь NULL? Ладно, но это уже твоя ответственность».

Результат: меньше сбоев, больше стабильности.

Zig также обеспечивает безопасное индексирование массивов (array[idx]). В C очень легко выйти за границы массива и начать портить память — в Zig такого не случится: он следит за индексами и не даёт коду «сойти с ума».

Вывод: Zig решает эти проблемы, просто убирая многие «подводные камни» из работы с указателями и добавляя дополнительные защитные механизмы.

На первый взгляд может показаться, что Zig — слишком идеалистичный проект. Обещает простоту, безопасность и мощную систему сборки так, что это звучит почти неправдоподобно. Но на самом деле Zig — не утопия. Все его возможности уже работают здесь и сейчас. Это не мечты о будущем, а реально работающий инструмент для современных проектов. Сила Zig — в том, что он выполняет свои обещания уже сегодня.

Если вам интересно увидеть применение этих инструментов на практике — загляните в Главу 13 «Zig в реальном мире». Там вы найдёте примеры того, как Zig помогает решать настоящие задачи разработки.

# Где использовать Zig

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

  • Встраиваемые системы: прямой контроль над ресурсами и управление памятью делают Zig идеальным выбором для разработки под встраиваемые устройства.
  • Операционные системы: детерминизм и точный контроль над железом позволяют писать ОС, драйверы и другое низкоуровневое ПО.
  • Кроссплатформенная разработка: мощные средства кросс-компиляции упрощают создание приложений для разных платформ.
  • Разработка игр: высокая производительность и контроль над ресурсами делают Zig отличным выбором для игр и игровых движков.
  • Сетевые инструменты: сочетание безопасности и производительности позволяет создавать эффективные сетевые сервисы и утилиты.
  • Интеграция с C/C++: Zig бесшовно взаимодействует с существующими проектами на C/C++, что удобно для их расширения или оптимизации.

Однако стоит помнить: несмотря на весь ажиотаж вокруг Zig, он пока не готов к массовому внедрению в разработку реальных систем. Ожидайте регулярных изменений API и рефакторинга до выхода стабильной версии 1.0. Это естественный этап развития языка.

Вы сделали первый шаг к изучению Zig. Не переживайте из-за трудностей на старте — у каждого пути свои повороты, а у каждого уровня свои вызовы. Главное — двигаться вперёд и получать удовольствие от процесса! С Zig вы становитесь частью сообщества новаторов, которые расширяют границы возможного в разработке ПО.

# Итоги

В завершение этой главы вы получили представление о том, что предлагает Zig. Теперь вы знаете, почему этот язык выбирают те, кто устал от причуд и сложностей C/C++. Мы обсудили, как Zig сочетает простоту и безопасность, избавляя от головной боли с управлением памятью. Всё это — фундамент для дальнейшего освоения языка.

Дальше мы перейдём к настройке среды разработки: подготовим всё необходимое для написания, тестирования и сборки кода на Zig. Здесь теория встретится с практикой — пора браться за дело! Готовы продолжить? Тогда вперёд!