Один способ дать имя значению
В Zero значению дают имя через let:
let answer = 42
Это весь синтаксис. Нет ни var, ни const, ни auto. Одно ключевое слово для привязок держит язык маленьким — и агенты, и люди учат его один раз и применяют везде.
let вводит локальную привязку в текущей области видимости. После этой строки answer отсылает к 42 до конца окружающего блока.
Вывод типов
Компилятор выводит тип из правой части. У литерала 42 тип по умолчанию i32, поэтому answer — это i32. Литерал "hello" — это строка, так что:
let greeting = "hello"
привязывает greeting к строковому значению. Если вы вызовете функцию, возвращающую Pair<i32, u8>, у привязки будет тип Pair<i32, u8>:
let pair = makePair(40, 2_u8)
Не приходится писать тип на каждой привязке, и код остаётся читаемым.
Явные аннотации типов
Когда хотите задокументировать тип — или зафиксировать конкретный, отличный от выведенного, — напишите тип после двоеточия:
let count: u8 = 10
let pair: Pair<i32, u8> = makePair(40, 2_u8)
Аннотации — это также подсказка компилятору, когда литерал может быть одним из нескольких типов. Литерал 10 мог бы быть i32, i64, u8 и так далее; аннотация это фиксирует.
Встретятся и типизированные суффиксы на литералах как альтернатива аннотированию привязки:
let small = 10_u8 // u8 из суффикса литерала
let big = 10_i64 // i64 из суффикса литерала
Обе формы валидны; выбирайте ту, что делает намерение яснее в месте вызова.
Привязки в деле
Разобранный пример, использующий и выведенную, и явную форму — нажмите Run, чтобы попробовать:
point аннотирован явно, потому что правая часть — это литерал структуры. total выводится — sum объявлена возвращать i32, поэтому и привязка i32.
Область видимости и затенение
let-привязка валидна от строки, в которой объявлена, до конца окружающего блока. Вложенные блоки создают новые области видимости:
pub fun main(world: World) -> Void raises {
let value = 1
if true {
let value = 2 // затеняет внешний 'value' внутри этого блока
// здесь value == 2
}
// снова за пределами if, value == 1
}
Внутренний value не мутирует внешний — это отдельная привязка, которая выходит из области видимости на закрывающей скобке блока if. Это та же модель, что у Rust и языков ML-семейства. Особенно часто это используется, когда вы хотите трансформировать значение через серию шагов, не выдумывая каждому промежуточному результату новое имя.
Чего let не делает
Несколько вещей, которые вы могли бы ожидать от других языков, но которых let намеренно не делает:
- Объявления только типа. Формы
let x: i32;, вводящей неинициализированную привязку, нет. Привязка обязана иметь значение в момент объявления. - Деструктуризация по паттерну (пока). В некоторых языках можно написать
let (a, b) = pair. Zero маленький по дизайну и сейчас фокусируется на простых привязках имени — сверьтесь с актуальной документацией, появилась ли деструктуризация. - Несколько ключевых слов для разных времён жизни. Никаких отдельных
static,const,let mutили блочно/функционально-областных вариантов. Одно ключевое слово.
Если ваш бэкграунд — JavaScript, ближайшая аналогия — const: имя, привязанное к значению до конца блока, с затенением во внутренних областях. Если ваш бэкграунд — Rust, let здесь играет ту же роль, что и let в Rust, минус явное ключевое слово mut.
Паттерн: построение значения шаг за шагом
Привязки сияют, когда вы хотите написать вычисление как серию именованных промежуточных шагов. Это хорошо и для людей, и для агентов, рассуждающих локально о каждой строке:
Каждая строка вводит один новый факт, с которым работает остальная функция. Компилятор всё равно производит плотный код — у именования промежуточных значений нет рантайм-стоимости.
Дальше: примитивные типы
let мало что значит без того, что привязывать. Следующая статья проходит по примитивным типам Zero — разрядностям целых, плавающим, строкам и типам Void и Bool, которые встретите чаще всего.
Часто задаваемые вопросы
Как объявить переменную в Zero?
Используйте let. Форма — let name = value для типа, выведенного автоматически, или let name: Type = value, чтобы прописать тип явно. Например: let answer = 42 или let answer: i32 = 42. Обе формы привязывают имя answer к значению 42 в текущей области видимости.
Выводит ли Zero типы у let-привязок?
Да. Если написать let total = sum(point), и sum возвращает i32, тип привязки выведется как i32. Аннотировать тип можно явно, когда хочется задокументировать его или зафиксировать конкретный — например, let count: u8 = 10.
Изменяемы ли let-привязки в Zero?
Обычный let вводит локальную привязку для использования в своей области видимости. История с изменяемостью в pre-1.0 Zero ещё эволюционирует — язык упирает на явные эффекты и предсказуемую память, поэтому всё, что мутирует состояние через привязку, должно делать это видимо. Сверьтесь с актуальной документацией Zero на счёт точного синтаксиса изменяемости в вашей версии тулчейна.
В чём разница между let и const в Zero?
Zero использует let для обычных локальных привязок внутри тел функций. Он не выставляет несколько ключевых слов для привязок, как let/const/var в JavaScript — держать поверхность маленькой это намеренный выбор. Константы времени компиляции обычно выражают через систему типов или объявления верхнего уровня, а не через отдельное ключевое слово.
Можно ли переобъявить let-привязку в Zero?
Привязки живут в окружающей области видимости. Новый let с тем же именем во вложенной области — это отдельная привязка, которая затеняет внешнюю на время внутренней области; на внешнюю это не влияет после того, как внутренняя область кончится. Это та же модель, что у Rust и языков ML-семейства.