Shanraq.org Shanraq.org
Переменные, значения и типы
IT

Rust: с нуля до своего органайзера Урок 9 из 10

Переменные, значения и типы

Урок 9. Предсказать значения и различить изменение и новое объявление.

Текст переведён с помощью ИИ.

Предварительно: уроки 1–8.

Зачем это нужно

До сих пор программа выводила заранее записанный текст. Значение — конкретные данные, например число 2. Переменная связывает имя со значением. Образ — подписанное место для данных. Позже увидим границу образа: имя не всегда означает отдельную коробку с независимой копией.

Тип определяет допустимые значения и действия. Образ — правила для содержимого: число можно использовать в арифметике, а текст — в текстовых операциях. Название переменной само по себе не задаёт её тип.

Сразу целиком

Замените src/main.rs, сохраните и выполните cargo run:

fn main() {
    let mut count: u32 = 2;
    println!("Было: {count}");
    count = 3;
    println!("Стало: {count}");
}

Вывод программы:

Было: 2
Стало: 3

Читаем объявление по частям

let объявляет переменную. mut разрешает изменять её значение присваиванием. count — выбранное имя («количество»); в учебных программах используем понятные латинские имена. : u32 — аннотация типа, явное указание беззнакового целого числа на 32 битах. Бит — двоичная единица, которая принимает одно из двух значений; число битов ограничивает диапазон числа. «Беззнаковое» означает без отрицательных значений; точные диапазоны — следующий урок. = задаёт значение, это не проверка равенства. 2 — числовой литерал. ; завершает инструкцию.

В println! запись {count} внутри текста подставляет значение переменной. Эти фигурные скобки внутри строки не являются блоком Rust. После count = 3 имя остаётся тем же и тип не меняется. Без mut повторное присваивание запрещено.

Выведение типа

Аннотацию иногда можно опустить: компилятор определит тип по значению и использованию. Это выведение типа, а не отсутствие типа. При простом let count = 2 без других ограничений получается i32, целое со знаком. Для учебного счётчика явно пишем u32 и не заставляем новичка угадывать контекст.

Другие примеры значений: true и false имеют тип bool («да/нет»), ‘A’ — char, одно скалярное значение Unicode — допустимый числовой код в общей системе обозначения символов. Видимый знак может состоять из нескольких таких значений; к этому вернёмся в уроке о тексте. “Rust” — строковый литерал типа &str. Одинарные и двойные кавычки различаются. &str — ссылка на текст, а не изменяемая строка; пока выводим литералы, владение текстом разберём в уроке 22. Логические действия подробно появятся в уроке 11. Эти определения нужны сейчас, чтобы слово «тип» не означало только числа.

Проверьте разные типы в одной короткой программе. true печатается как true: Rust не переводит логическое значение на язык страницы. Имена ready, mark и title означают «готово», «отметка» и «название». Фигурные скобки внутри строки println! подставляют значение по имени, как {count} выше.

fn main() {
    let ready: bool = true;
    let mark: char = 'A';
    let title: &str = "Rust";
    println!("{ready}");
    println!("{mark}");
    println!("{title}");
}
true
A
Rust

Новое объявление и область видимости

Новое let с прежним именем создаёт новую привязку — затенение, а не присваивание старой переменной. Область видимости — часть программы, где доступно имя. Внутренний блок может иметь свою переменную, а после него снова видна внешняя:

fn main() {
    let count = 2;
    {
        let count = 3;
        println!("Внутри: {count}");
    }
    println!("Снаружи: {count}");
}

Вывод программы:

Внутри: 3
Снаружи: 2

Имена констант обычно пишут заглавными латинскими буквами, разделяя слова знаком _: DAILY_LIMIT означает «дневной предел».

const объявляет константу, значение, вычисляемое при компиляции. Её тип указывают явно; mut к ней не применяют. Обычная неизменяемая переменная может получить значение во время выполнения, поэтому это не одно и то же.

const DAILY_LIMIT: u32 = 5;

fn main() {
    println!("План: {DAILY_LIMIT}");
}

Вывод программы:

План: 5

Намеренная ошибка: здесь забыли разрешить изменение. Ожидается E0384, а не вывод:

fn main() {
    let count = 2;
    println!("Было: {count}");
    count = 3;
    println!("Стало: {count}");
}

Опорная карта

Значение → имя → тип → допустимые действия. let создаёт привязку; mut разрешает присваивание; новое let затеняет; блок ограничивает видимость; const задаёт константу.

Разминка

  1. Предскажите внешний count после внутреннего блока.
  2. Заполните: let ___ count: u32 = 4; чтобы затем присвоить 5.
  3. Почините пример E0384, не заменяя переменную константой.

Задание

Обязательное. Создайте изменяемый счётчик u32 со значением 4, выведите «Было: 4», присвойте 5, выведите «Стало: 5». Затем устно объясните, почему это не затенение.

На своих данных. Выберите два других неотрицательных небольших числа.

Подсказка и эталон

Эталон приведён ниже. В нём только одно let и последующее присваивание. Если вы не можете отличить mut от нового let, повторите два примера отдельно; идти к арифметике пока необязательно.

Сверка после самостоятельной попытки

Внешний count остаётся равным 2; пропуск — mut; в ошибочном примере достаточно разрешить изменение переменной.

fn main() {
    let mut count: u32 = 4;
    println!("Было: {count}");
    count = 5;
    println!("Стало: {count}");
}

Ожидаемый вывод эталона:

Было: 4
Стало: 5

Предыдущий урок · Оглавление · Следующий урок

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Комментарии (0)

Пока нет комментариев. Будьте первым.