Основы языка

Операторы и выражения

Проследите значения арифметики, сравнений и сокращённых вычислений и отличите их от присваивания.

Выражение нужно там, где программа должна получить значение. Арифметика, сравнение, вызов функции, if и match могут возвращать результат. Присваивание решает другую задачу: изменяет существующее изменяемое место и является инструкцией, а не значением для вложенного выражения.

Начните с наблюдаемого результата

Сохраните код в operators-expressions.tpz:

TOPAZ
function score(base: int, bonus: int) -> int {
    let doubled = base * 2
    if bonus > 0 { doubled + bonus } else { doubled }
}

let result = score(20, 2)
let exact = result == 42
let changed = result != 41

print("{result} {exact} {changed}")

Проверьте и запустите файл:

BASH
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, перегрузка и пользовательские операторы сейчас отсутствуют. Композиция функций существует на уровне спецификации, но обычные примеры этой документации используют именованные функции или |>.

Допустимые типы описаны в разделе Типы, ветвящиеся значения — в Шаблоны и управление потоком, а точное поведение |> — в Конвейеры и заполнители.