Переменные, mut и типы

Переменные в Rust неизменяемы по умолчанию; разбираем let, mut, затенение (shadowing) и базовые типы.

Неизменяемость по умолчанию — объявленная через let переменная не может быть изменена, пока вы явно не разрешите это словом mut.

let и неизменяемость

Переменные объявляются через let. И тут первый сюрприз для пришедших из других языков: по умолчанию переменная неизменяема. Попытка присвоить ей новое значение — ошибка компиляции.

fn main() {
    let x = 5;
    // x = 6;   // ОШИБКА: cannot assign twice to immutable variable `x`
    println!("x = {x}");
}

Это не каприз языка, а защита. Неизменяемые значения проще понимать: вы уверены, что никакая строчка ниже их не поменяет. Поэтому Rust заставляет вас осознанно отмечать те переменные, которые действительно должны меняться.

mut — осознанная изменяемость

Чтобы переменную можно было менять, добавляют mut (от mutable).

fn main() {
    let mut count = 0;
    count = count + 1;
    count += 1;
    println!("count = {count}");
}

Вывод:

count = 2

Затенение (shadowing)

Можно объявить новую переменную с тем же именем — это называется затенением. Старое значение «прячется» за новым. В отличие от mut, затенение создаёт новую переменную и потому может поменять даже тип.

fn main() {
    let spaces = "   ";          // строка
    let spaces = spaces.len();    // теперь число — другой тип!
    println!("длина = {spaces}");
}

Вывод:

длина = 3

С mut так нельзя: изменяемая переменная не меняет тип. Затенение часто используют, чтобы преобразовать значение и переиспользовать удобное имя, не плодя spaces_str, spaces_num и так далее.

mutshadowing
Создаёт новую переменную?нетда
Может сменить тип?нетда
Нужно словоmutповторный let

Базовые типы

Rust статически типизирован, но обычно выводит типы сам. При желании тип указывают явно через двоеточие: let x: i32 = 5;.

КатегорияТипы
Целые со знакомi8, i16, i32, i64, isize
Целые без знакаu8, u16, u32, u64, usize
Дробныеf32, f64
Логическийbool (true / false)
Символchar (один символ Unicode, в одинарных кавычках)

По умолчанию целое — это i32, дробное — f64. Тип usize используется для индексов и размеров: его ширина совпадает с разрядностью платформы.

fn main() {
    let age: u32 = 30;
    let pi = 3.14159_f64;
    let is_rust_fun = true;
    let letter = 'R';
    println!("{age} {pi} {is_rust_fun} {letter}");
}

Вывод:

30 3.14159 true R

Итог

  • Переменные неизменяемы по умолчанию; чтобы менять — добавьте mut.
  • Затенение (повторный let) создаёт новую переменную и может сменить тип; mut — не может.
  • Типы обычно выводятся; целое по умолчанию i32, дробное — f64, индексы — usize.
Проверьте себя
1. Можно ли изменить переменную, объявленную просто через let x = 5?
AДа, в любой момент
BНет, она неизменяема, пока не добавить mut
CТолько внутри функций
DТолько если она число
2. Чем затенение (shadowing) отличается от mut?
AНичем
BЗатенение создаёт новую переменную и может сменить тип, а mut — нет
CЗатенение работает только с числами
Dmut создаёт новую переменную
3. Какой тип у целого числа по умолчанию в Rust?
Ai64
Bu32
Ci32
Dusize
Поддержать проект