Основы языка

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

Вычисление арифметических выражений, сравнений и коротких вычислений, а также их отличие от присваивания.

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

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

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

TOPAZ
function оценить(основа: int, бонус: int) -> int {
    let удвоенное = основа * 2
    if бонус > 0 { удвоенное + бонус } else { удвоенное }
}

let результат = оценить(20, 2)
let точно = результат == 42
let изменилось = результат != 41

print("{результат} {точно} {изменилось}")

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

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

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