Раздел 41 · Zig с нуля

comptime: код на этапе компиляции

junior~10 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

comptime: код на этапе компиляции

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

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

Одна мысль урока

comptime требует вычисления до запуска и работает только с доступными в этот момент данными.

Опора из прошлого урока: Сравнение с ручной памятью C и Rust.

От картинки к записи

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

У массива длина входит в тип: [N]u8. Поэтому N должна быть известна до запуска. Если N вычисляется из константного размера стороны квадратной сетки, это удобный случай для comptime. Если длина прочитана из файла во время работы, её нельзя без другого представления превратить в тип нового массива. Для такой длины нужен срез и, возможно, аллокатор.

В примере функция square обычная: принимает usize, возвращает usize. Вызов comptime square(3) требует получить девять при компиляции. На основе девяти создаётся тип массива. Во время теста проверяем уже готовый массив и его длину. Это не обещание, что любая строка после const выполнится заранее.

Различай неизменяемость и время вычисления. const input = прочитанное_число может хранить значение, известное только после запуска. Оно не меняется, но компилятор не знает его заранее. comptime добавляет именно требование доступности до выполнения. Если сведения отсутствуют, компилятор не угадывает их по имени.

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

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

Ранние вычисления тоже стоят времени. Большая таблица, создаваемая компилятором, может увеличить время сборки и размер файла. Не делай вывод «comptime всегда ускоряет всё». Он переносит работу и позволяет описать часть программы значениями. Полезность определяется тем, что именно известно заранее и сколько разных вариантов приходится строить.

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

премиум-урок

Продолжение в премиуме: 1 200 ₽ в месяц или 10 000 ₽ в год. Вместе с ним серверные проверки задач и школьные токены AI-коуча.

Оплата пока не подключена: премиум и курсы открываются промокодом.