Философия явности: что отличает Zig от C
В кафе тебе предлагают два чека. На одном только общая сумма. На другом отдельные строки: напиток, доставка, упаковка. Во втором легче найти неожиданную доплату. Явный код похож на подробный чек: действия не исчезают, зато можно увидеть их цену и место.
Посмотрим на скромную задачу: из большой числовой величины получить маленькую. Мы не будем учить весь C. Сравнение нужно только для одного вопроса: в какой строке автор согласился изменить представление значения?
Одна мысль урока
Явность означает видимое решение, а не отсутствие удобных сокращений.
Опора из прошлого урока: Установка Zig и первая программа.
От картинки к записи
В Zig преобразование в более узкий числовой тип часто требует отдельной записи. u16 содержит числа до 65535, u8 только до 255. Из первого типа нельзя бездумно сделать второй: значение 300 не помещается. Когда компилятор видит такое несоответствие, он просит автора выбрать действие, а не догадывается о намерении.
Преобразование типа
может быть безопасным расширением либо сокращением диапазона. Расширение u8 в u16 сохраняет все
числа исходного диапазона. Обратный путь требует проверки. @intCast говорит «это значение должно
помещаться» и проверяется в безопасных режимах. @truncate говорит «оставь младшие биты». Эти
записи отвечают на разные задачи и не заменяют друг друга.
Ниже проверяем границу до преобразования. Функция clampByte принимает u16, а возвращает u8. Условие выбирает максимум 255, если вход больше. После этого @intCast работает с гарантированно подходящим числом. Сначала принимается смысловое решение, затем выполняется техническое преобразование. Это хороший порядок: сперва договор о поведении, потом способ его записать.
В C многие числовые преобразования происходят при присваивании. Это не делает C плохим языком, но меняет цену чтения: часть правил нужно помнить вне строки. Zig чаще заставляет подписать намерение. Не все преобразования запрещены: полезное безопасное расширение по-прежнему может быть неявным. Поэтому лозунг «в Zig вообще нет неявных преобразований» неточен.
Явность касается и ошибок. Если функция может не выполнить работу, в типе её результата появляется возможность ошибки. Вызывающий выбирает: вернуть её выше или обработать здесь. Подробно разберём оба варианта отдельно. Сегодня достаточно не путать ошибку, предусмотренную договором функции, с остановкой из-за неправильного обращения с памятью.
Явность касается динамической памяти. Вызов, которому нужны новые байты, получает аллокатор. Внешне это лишний параметр, зато читатель видит, где может не хватить памяти и кто её выдаёт. Мы ещё не пишем такой код, но уже знаем, на какой вопрос смотреть в сигнатуре функции.
Удобные сокращения не противоречат явности. try короче ручного разбора ошибки, но само слово отмечает возможный выход. defer короче повторения очистки в каждой ветке, но место постановки очистки видно. Важен не размер строки, а возможность восстановить путь данных и управления.
премиум-урок
Продолжение в премиуме: 1 200 ₽ в месяц или 10 000 ₽ в год. Вместе с ним серверные проверки задач и школьные токены AI-коуча.
Оплата пока не подключена: премиум и курсы открываются промокодом.