Выражение используется там, где программа должна получить значение. Арифметика, сравнения, вызовы функций, if и match могут возвращать результат. Присваивание решает другую задачу. Оно изменяет существующее изменяемое место и является инструкцией, а не значением для вложенного выражения.
Начните с наблюдаемого результата
Сохраните код в operators-expressions.tpz:
function оценить(основа: int, бонус: int) -> int {
let удвоенное = основа * 2
if бонус > 0 { удвоенное + бонус } else { удвоенное }
}
let результат = оценить(20, 2)
let точно = результат == 42
let изменилось = результат != 41
print("{результат} {точно} {изменилось}")Проверьте и запустите файл:
topaz check operators-expressions.tpz
topaz run operators-expressions.tpzРезультат:
42 true trueВыражение base * 2 вычисляется раньше + bonus, а выбранная ветвь if становится результатом функции. Оператор == проверяет равенство двух сравнимых значений, а != — их различие. Ни один из этих операторов не изменяет привязку.
Выберите оператор по задаче
| Задача | Форма | Важное различие |
|---|---|---|
| Арифметика | +, -, *, /, %, ** | Оба операнда принадлежат одному типу — int или float |
| Порядок или равенство | <, <=, >, >=, ==, != | Допустимы только сравнимые типы |
| Принадлежность | value in collection | Для Map поиск выполняется по ключам, а не через value in map |
| Условное вычисление | left && right, left || right | Правая часть вычисляется только при необходимости |
| Значение по умолчанию | value ?? fallback | Объединяет nullable-значение или Option с запасным |
| Передача ошибки Result | постфиксный value? | Возвращает Err из окружающей функции; это не ?? |
| Поток слева направо | value |> next | Подчиняется правилам конвейера |
| Изменение | target = value, +=, ??= | Инструкция, а не выражение со значением |
&& вычисляет правую часть только при истинной левой, а || — только при ложной. Такое сокращённое вычисление защищает от выполнения операций, допустимых лишь после успешной первой проверки. ?? также пропускает запасной вариант, когда слева уже есть значение. Постфиксный ? задаёт другую границу. Раздел Null, Option, Result и ошибки объясняет возврат ошибки из окружающей функции.
Границы чисел и равенства
int — знаковое 64-битное целое. Целочисленное деление округляется к нулю, а остаток получает знак делимого. Переполнение, деление на ноль и отрицательная целая степень, определившаяся во время выполнения, приводят к ошибке выполнения. Та же недопустимая операция в константном выражении даёт статическую ошибку. float соответствует стандарту IEEE-754 binary64, включая деление на ноль и NaN. Неявного преобразования между int и float нет.
Примитивные значения, совместимые записи, Array, Option, Result и именованные значения сравнимы лишь тогда, когда сравнимы их части. Для Array учитываются длина и порядок элементов. Значения Map и Set, функции, ресурсы и шаблоны несравнимы. Для именованных значений сначала должна совпасть сущность enum, record или newtype.
По убыванию приоритета идут вызовы и доступ к членам, возведение в степень, унарные операторы, умножение, сложение, диапазоны, сравнения, &&, ||, ??, композиция и, наконец, |>. Запоминать всю таблицу необязательно. Если группировка важна для понимания, покажите её круглыми скобками.
Частая ошибка
Записи count++, count-- и count **= 2 не относятся к Топазу. Изменяемой привязке присваивают явно, как в count = count + 1. Не путайте = с равенством. = изменяет цель, а == создаёт логическое значение.
Битовые операторы, неявное числовое повышение, оператор остатка для float, перегрузка и пользовательские операторы сейчас отсутствуют. Композиция функций существует на уровне спецификации, но обычные примеры этой документации используют именованные функции или |>.
Допустимые типы описаны в разделе Типы, ветвящиеся значения — в Шаблоны и управление потоком, а точное поведение |> — в Конвейеры и заполнители.