Переменные, 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 и так далее.
| mut | shadowing | |
| Создаёт новую переменную? | нет | да |
| Может сменить тип? | нет | да |
| Нужно слово | 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.