Метапрограммирование без макросов
У архивариуса есть описание карточки: названия полей и их виды. Вместо переписывания одинаковой проверки для каждой карточки он читает это описание. Компилятор тоже знает поля структуры и может использовать знание при подготовке программы.
Сегодня проверим простой договор: функция принимает только структуру, а результатом заранее становится количество её полей. Это маленький пример метапрограммирования без замены текста.
Одна мысль урока
Метапрограммирование использует сведения о типах для проверки и построения обычного кода.
Опора из прошлого урока: Дженерики через comptime-типы.
От картинки к записи
Метапрограммирование
звучит сложнее своей первой задачи. Мы хотим спросить у компилятора, что представляет собой T, и
сделать решение на основе ответа. Для этого Zig предоставляет @typeInfo(T), описание свойств типа.
Результат @typeInfo представлен помеченным объединением: целое число, указатель, структура и другие категории имеют разные сведения. Для структуры используется тег .@"struct". Кавычки нужны, потому что struct занято ключевым словом, а здесь оно используется как имя варианта.
У описания структуры есть список fields. Его длина fields.len известна при компиляции. Функция fieldCount может вернуть её как число. В примере у карточки два поля, поэтому результат два. Это не чтение памяти конкретного объекта: мы не создаём экземпляр и не заглядываем в его значения.
@compileError останавливает компиляцию с твоим сообщением. Если в функцию передадут не структуру, ошибка появляется заранее, а не как произвольное число во время работы. Это полезно для понятных договоров обобщённой функции. Проверка должна описывать реальное ограничение, не прикрывать неправильную реализацию.
Чтобы пройти поля и обращаться к каждому по имени, часто нужен inline for. Его итерации разворачиваются при компиляции, поэтому имя поля доступно как comptime-значение. @field(value, field.name) выбирает соответствующее поле. Обычный цикл по пользовательским данным решает другую задачу: число и содержание элементов может стать известно только после запуска.
Макросы
в стиле текстовой подстановки нам не понадобились. Zig использует значения, типы, условия и циклы того же языка. Это упрощает связь с уже изученной записью, но не делает сложную генерацию автоматически понятной.
Не начинай с генератора всего приложения. Небольшая проверка числа полей уже полезна для схемы данных, теста или компактного универсального помощника. Если функция сохраняет понятный результат и короткий договор, её легче сопровождать через несколько месяцев.
Раскрутка кода имеет цену. Если у тебя сотни типов с сотнями полей, компилятору нужно обработать соответствующее число действий. Размер программы тоже может вырасти. Поэтому метапрограммирование выбирают ради повторяющегося договора, а не ради самого наличия необычных встроенных функций.
премиум-урок
Продолжение в премиуме: 1 200 ₽ в месяц или 10 000 ₽ в год. Вместе с ним серверные проверки задач и школьные токены AI-коуча.
Оплата пока не подключена: премиум и курсы открываются промокодом.