Шаг 1. Переменные и типы
Зачем#
Большинство ошибок в программах — это значения, которые изменились не там и не тогда, когда вы ожидали. Поэтому в OxL
привязка по умолчанию неизменяема: let создаёт имя, которое нельзя переприсвоить. Если значение должно меняться, это надо
сказать явно словом var — и читатель кода сразу видит, какие переменные «живые».
Типы статические, но их почти не приходится писать: компилятор выводит тип из значения. Типы нужны в сигнатурах функций и там, где значение неочевидно (§3).
Пример#
fn main() io {
let name = "Ann" // let — неизменяемая привязка; тип str выведен
var visits = 0 // var — изменяемая переменная
visits += 1
visits += 1
let ratio: f64 = 2.5 // тип можно указать явно
let big = 1_000_000_i64 // суффикс и разделители в числах
let letter = 'x'
let ok = visits == 2 && !name.isEmpty()
print("{name} visited {visits} times, ratio {ratio}, big {big}") // {…} в строке — интерполяция
print("{letter} {ok} {name.len()} {name.upper()}")
let (a, b) = (10, 3) // кортеж и его разбор
print("{a / b} {a % b} {a as f64 / b as f64}")
let nothing: i32? = none // i32? — «значение или none»
print("{nothing ?? 42}") // ?? подставляет значение по умолчанию
}Ann visited 2 times, ratio 2.5, big 1000000 x true 3 ANN 3 1 3.3333333333333335 42
Разбор#
let name = "Ann"— неизменяемая привязка типаstr. Строки — это текст UTF-8; их копирование дешёвое.var visits = 0— изменяемая переменная целого типа (тип выводится). Операции+=,-=и т. д. требуютvar.1_000_000_i64— разделитель_для читаемости и суффикс типа. Основные числовые типы:i8…i128,u8…u128,usize,f32,f64. Арифметика проверяет переполнение:+,-,*при выходе за диапазон паникуют, а не молча заворачиваются (явные варианты —+%с переносом и+|с насыщением, §3.1)."{name} visited {visits} times"— в строку можно вставить любое выражение в фигурных скобках.(a, b)— кортеж;let (a, b) = …раскладывает его на части.10 / 3— целочисленное деление, поэтому для вещественного результата числа приводятсяas f64.i32?— «i32илиnone». Значениеnone— единственный способ выразить «нет значения»:nullв языке нет.a ?? bберётa, если оно есть, иначеb.
Типичная ошибка: изменение let#
Если вы попытаетесь изменить неизменяемую привязку, компилятор остановит сборку и подскажет, что нужен var:
fn main() {
let count = 0
count += 1 // let неизменяем
}mutate-immutable
Диагностика: mutate-immutable. Исправление — объявить var count = 0.
Вторая частая ошибка — несовпадение типов. OxL не приводит типы молча: строку нельзя положить в i32, а i32 в i64
без явного as:
fn main() {
let count: i32 = "five"
}type-mismatch
Диагностика: type-mismatch. И опечатка в имени — unresolved-name — тоже ловится на этапе компиляции:
fn main() {
let total = 10
print(totl)
}unresolved-name
Что запомнить#
let— по умолчанию;var— только там, где значение действительно меняется.- Числа и строки не приводятся друг к другу неявно.
- Отсутствие значения — это тип
T?, а не специальныйnull; компилятор заставляет вас учестьnone.
Дальше: функции.