Перейти к содержимому

Переменные в Rust

Переменная — это просто имя, которое ты даёшь значению, чтобы пользоваться им потом. Представь подписанную коробку: кладёшь в неё что-то, пишешь на ней имя и дальше обращаешься к ней по имени, а не повторяешь значение повсюду.

В Rust переменная создаётся ключевым словом let:

fn main() {
let age = 30;
println!("Мне {age} лет");
}

Вывод:

Мне 30 лет
▶ Попробуй сам

Разберём эту строку:

  • let — говорит Rust: «Я создаю новую переменную».
  • age — имя, которое мы выбрали.
  • = — присваивает значение справа имени слева.
  • 30 — значение, которое мы сохраняем.

{age} внутри println! выводит значение переменной. Это называется интерполяцией строк: Rust подставляет вместо {age} то, что лежит в age.

У каждого значения в Rust есть тип (целое число, текст, true/false и так далее). Можно подумать, что тип нужно указывать, но обычно этого делать не приходится: Rust смотрит на значение и сам всё понимает. Это называется выводом типов (type inference).

fn main() {
let score = 95; // Rust понимает, что это целое число
let name = "Феррис"; // Rust понимает, что это текст
let is_active = true; // Rust понимает, что это логическое значение
println!("{name}: {score}, активен = {is_active}");
}

Вывод:

Феррис: 95, активен = true
▶ Попробуй сам

Если хочется указать тип явно, его можно написать после двоеточия:

let score: i32 = 95; // i32 = 32-битное целое число

А вот что удивляет тех, кто пришёл из других языков: в Rust после того, как переменной задано значение, изменить его по умолчанию нельзя. «Неизменяемая» (immutable) значит именно это — её нельзя изменить.

Этот код не скомпилируется:

fn main() {
let count = 1;
count = 2; // ❌ ошибка: нельзя дважды присвоить значение неизменяемой переменной
println!("{count}");
}

Компилятор остановит тебя понятным сообщением:

error[E0384]: cannot assign twice to immutable variable `count`

Оно означает: «нельзя дважды присвоить значение неизменяемой переменной count». Зачем языку делать так специально? Потому что множество ошибок появляется, когда значения меняются там, где ты этого не ждёшь. Когда ничего не меняется, пока ты сам не попросишь, код становится предсказуемее. Это возможность, а не ограничение.

Делаем переменную изменяемой с помощью mut

Заголовок раздела «Делаем переменную изменяемой с помощью mut»

Когда значение действительно должно меняться, добавь ключевое слово mut (от mutable — изменяемый):

fn main() {
let mut count = 1;
println!("До: {count}");
count = 2; // ✅ теперь можно — благодаря `mut`
println!("После: {count}");
}

Вывод:

До: 1
После: 2
▶ Попробуй сам

Rust позволяет объявить новую переменную с тем же именем, что и у старой. Это называется затенением (shadowing): новая переменная «отбрасывает тень» на старую:

fn main() {
let x = 5;
let x = x + 1; // новая x на основе старой -> 6
let x = x * 2; // ещё одна новая x -> 12
println!("x равно {x}");
}

Вывод:

x равно 12
▶ Попробуй сам

Похоже на mut, но это другое:

  • mut меняет значение той же самой переменной.
  • Затенение создаёт совершенно новую переменную, которая просто использует то же имя, — и у неё даже может быть другой тип.

Затенение удобно, когда нужно преобразовать значение, но продолжать пользоваться тем же именем:

fn main() {
let spaces = " "; // текст
let spaces = spaces.len(); // теперь число (сколько пробелов)
println!("Количество пробелов: {spaces}");
}

Вывод:

Количество пробелов: 3
▶ Попробуй сам

Константа — это значение, которое никогда не меняется и известно уже на этапе компиляции. Она объявляется словом const вместо let, и тип обязательно нужно указать:

const MAX_SCORE: u32 = 100;
fn main() {
println!("Максимальный результат: {MAX_SCORE}");
}

Вывод:

Максимальный результат: 100
▶ Попробуй сам

По соглашению константы пишут в стиле UPPER_SNAKE_CASE. Вот чем они отличаются от обычных переменных:

Переменная let Константа const
Можно изменить? Только с mut Никогда
Нужен тип? Не обязательно (выводится) Обязательно
Стиль имени snake_case UPPER_SNAKE_CASE
Где можно объявить Внутри функций Где угодно, даже вне функций

Используй константу для значений, которые действительно неизменны, — например, количества секунд в минуте или какого-то максимального предела.

  • Используй snake_case — слова в нижнем регистре, соединённые подчёркиваниями: user_name, total_price.
  • В именах могут быть буквы, цифры и подчёркивания, но начинаться с цифры имя не может.
  • Выбирай понятные имена: age лучше, чем a. Имена принято писать по-английски, даже если комментарии на русском.

Создай переменную level со значением 1. Выведи её, дважды увеличь на 1 и выводи после каждого изменения, чтобы получилось Уровень 1, Уровень 2, Уровень 3. Подсказка: значению, которое меняется, нужен mut, а level = level + 1; прибавляет единицу.

Показать решение
fn main() {
let mut level = 1;
println!("Уровень {level}");
level = level + 1;
println!("Уровень {level}");
level = level + 1;
println!("Уровень {level}");
}

Вывод:

Уровень 1
Уровень 2
Уровень 3
▶ Попробуй сам

Объяви константу SECONDS_PER_MINUTE со значением 60. Начни с let time = 5; (в минутах), затем затени time, чтобы она хранила ту же длительность в секундах, и выведи Это 300 секунд. Подсказка: новую time можно получить из старой: let time = time * ...;.

Показать решение
const SECONDS_PER_MINUTE: u32 = 60;
fn main() {
let time = 5; // минуты
let time = time * SECONDS_PER_MINUTE; // новая `time`, теперь в секундах
println!("Это {time} секунд");
}

Вывод:

Это 300 секунд
▶ Попробуй сам

mut не нужен: второй let создаёт совершенно новую переменную с тем же именем. Кроме того, Rust здесь сам выводит, что time имеет тип u32, потому что её умножают на константу типа u32.

  • Переменные создаются через let; обычно Rust сам выводит тип.
  • Переменные по умолчанию неизменяемые — добавь mut, чтобы разрешить изменения.
  • Затенение заново объявляет имя через let и создаёт новую переменную (тип может поменяться).
  • Константы (const) никогда не меняются, всегда требуют тип и пишутся в UPPER_SNAKE_CASE.

Проверь себя

1. Можно ли по умолчанию заново присвоить значение переменной let в Rust?

2. Что такое затенение (shadowing) в Rust?

3. Какой стиль имён используют переменные в Rust, судя по этой странице?

Результат: 0 / 3