Основы
while выполняет своё тело, пока условие типа bool остаётся true:
while condition {
// тело
}
Компилятор вычисляет условие перед каждой итерацией:
true— выполнить тело, потом проверить снова.false— выйти из цикла.
Тривиальная иллюстрация из примеров Zero, с условием, которое уже false:
Запустите — сработает только второй write. Тело while ни разу не выполнится, потому что условие было false в момент первой проверки.
Условие — это bool
Как и в if/else, условие цикла должно быть bool. Zero не приводит целые, строки или другие значения к булеву.
while count { // compile error
// ...
}
while count > 0 { // ОК
// ...
}
Условие может быть чем угодно, что вычисляется в bool: привязкой, сравнением, комбинацией &&/|| или вызовом функции. Те же правила, что и у if.
Counted-циклы
Классический паттерн «сделать что-то N раз» использует счётчик и while:
let mut i = 0
while i < 10 {
// делаем работу
i = i + 1
}
Три кусочка: начальное значение, условие, сравнивающее со границей, и обновление в теле. Этот паттерн есть у каждого императивного языка — Zero просто не оборачивает его в ключевое слово for.
Заметка про mut выше: как именно Zero пишет изменяемые привязки в вашем тулчейне, может отличаться в pre-1.0 версиях. Запустите zero check --json против небольшого теста, чтобы убедиться в точном синтаксисе, который принимает ваш компилятор. Концептуальный паттерн (счётчик + условие + обновление) — стабильная часть.
Бесконечные циклы
while, условие которого всегда true, выполняется вечно:
while true {
// ждём работу, обрабатываем её, повторяем
}
Это правильная форма для event-loop, REPL или долгоживущего сервера. Чтобы выйти, либо завершите процесс, либо выбросите ошибку из тела, либо переструктурируйте, чтобы условие сломалось.
Когда тянуться к циклу
Циклы — инструмент, к которому стоит тянуться экономно. То, что выглядит как цикл в других языках, в Zero часто имеет более чистую форму:
- Итерация по фиксированной коллекции: предпочитайте функцию, которую выставляет стандартная библиотека или ваш shape —
forEach-помощник, фолдер или рекурсивный обход. - Чтение до конца ввода: циклите по fallible-чтению, но используйте
checkиraises, чтобы аккуратно обработать границу, а не вкладывать флаги состояния. - Polling условия: подумайте, не должен ли дизайн вместо этого дать вам сигнал. Polling-циклы — это запах в любом системном языке.
Тот же инстинкт применим и к агентам: плотная декларативная форма легче для рассуждения, чем рукописный счётный цикл, — и для людей, и для генераторов кода.
Циклы и эффекты
Тело while, как и любой другой блок, может делать I/O — но только если у него есть доступ к capability World (или его кусочку). Функция, в сигнатуре которой нет World, может крутить циклы сколько угодно, но не сможет ничего записать наружу. Это свойство верно и внутри тела цикла; цикл не предоставляет никаких новых capability.
Звучит очевидно, но именно поэтому можно положить while внутрь «чистой» вычислительной функции и всё равно по одной только сигнатуре знать, что она ничего не печатает и не пишет на диск.
Стиль
Несколько маленьких привычек, которые окупаются:
- Держите условие очевидным. Если условие делает реальную работу, вынесите его в именованную функцию или привязку, чтобы цикл читался чисто.
- Обновляйте счётчик внизу тела, а не разбросанно по нему. Так легче замечать ошибки на единицу.
- Предпочитайте условия раннего выхода, которые можно выразить как само условие цикла, флагам, переключающимся в середине итерации. Меньше движущихся частей.
Дальше: Shapes
Теперь вы видели весь основной поток управления Zero. Следующая глава — про моделирование данных, начиная с shapes, struct-подобных product-типов Zero.
Часто задаваемые вопросы
Как работают циклы while в Zero?
Используйте while condition { ... }. Условие вычисляется перед каждой итерацией; если оно true, выполняется тело, и цикл проверяет снова. Если false, цикл выходит, и выполнение продолжается за закрывающей скобкой. Условие должно быть bool.
Есть ли в Zero цикл for?
В ранней версии Zero поставляется только while как конструкция цикла. Язык намеренно держит поверхность маленькой, пока стабилизируется, — меньше ключевых слов означает меньше способов для агента выбрать не ту форму. for по диапазону или коллекции может появиться позже; пока тот же паттерн строится через while со счётчиком.
Как написать counted-цикл в Zero?
Инициализируйте счётчик, запустите while против него и обновляйте внутри тела: let mut i = 0; while i < 10 { ...; i = i + 1 }. Синтаксис изменяемости в pre-1.0 Zero ещё эволюционирует, поэтому сверьтесь с актуальной документацией о точном написании — но паттерн «while + счётчик + обновление» это стандартная идиома счётного цикла.
Есть ли в Zero break или continue?
Большинство языков из семейства Zero поставляют какую-то конструкцию раннего выхода для циклов; точное написание в pre-1.0 Zero — одна из областей, которые могут пошевелиться до 1.0. Консервативный подход — устроить цикл так, чтобы само условие делало работу: инвертировать и обновить условие так, чтобы цикл вышел естественно, а не полагаться на конкретное ключевое слово потока управления.
Может ли цикл while в Zero работать вечно?
Да — while true { ... } это бесконечный цикл. Полезно для серверов, event-loop, REPL — всего, где нет естественного условия завершения. В отличие от неявной truthiness, true здесь — это литерал типа bool, поэтому условие хорошо типизировано.