Shanraq.org Shanraq.org
Логические значения
IT

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

Логические значения

Урок 11. Записать и проверить условие отбора задач.

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

Предварительно: уроки 1–10. Если непонятны переменные, вернитесь к уроку 9.

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

Вспомните урок 10: числа позволяют посчитать задачи, но ещё не отвечают, какую задачу показывать. Теперь зададим правило: дело не выполнено и при этом либо важное, либо короткое. Логическое значение (boolean) — ответ из двух вариантов: true — истина, false — ложь. Тип этих значений — bool.

Представьте выключатель с двумя положениями. Но false не означает «плохая задача» и не означает «нет данных»: это только отрицательный ответ на конкретный вопрос. Мы пока сами задаём сведения в коде, не читаем их из терминала.

Запуск примера

Работаем в проекте organizer, созданном в уроке 6, в папке с Cargo.toml. Сохраните свою предыдущую работу отдельно. Замените весь src/main.rs первым примером ниже, сохраните файл и выполните cargo run в терминале этой папки. Как объяснялось в уроке 6, команда собирает и запускает программу. Остальные файлы менять не нужно; зависимости не добавляем. Каждый следующий полный пример также заменяет файл целиком. В блоке результата показан только вывод программы, без сообщений Cargo. Сначала предскажите его, потом запускайте.

Перед кодом разберём новые знаки. Сравнения >=, <= и != отвечают «не меньше», «не больше» и «не равно»; результат — bool. !done меняет ответ на противоположный. && требует истинности обоих условий, || — хотя бы одного. Скобки объединяют часть условия, как в арифметике. В slots != 0 && tasks / slots <= 2 сначала проверяется ненулевой делитель: если слева false, правая часть не вычисляется. Это правило порядка, а не способность компилятора угадывать опасное деление.

fn main() {
    let done: bool = false;
    let priority: u8 = 3;
    let minutes: u32 = 20;
    let show = !done && (priority >= 3 || minutes <= 15);
    println!("Показать: {show}");
    let slots: u32 = 0;
    let tasks: u32 = 6;
    let fits = slots != 0 && tasks / slots <= 2;
    println!("Поместится: {fits}");
}
Показать: true
Поместится: false

Разбор

done означает «выполнено», priority — важность, minutes — длительность, show — «показать». В этом учебном правиле важность 3 и выше считается высокой. let done: bool = false; задаёт тип явно; в show компилятор выводит его из выражения.

Запись Вопрос
a == b Равны ли значения?
a != b Различаются ли?
a < b, a <= b Меньше? Меньше или равно?
a > b, a >= b Больше? Больше или равно?

= задаёт значение, а == сравнивает. Сравнение возвращает bool. ! перед логическим значением меняет ответ на противоположный: !false даёт true. Это иной смысл восклицательного знака, чем часть имени макроса println!.

&& означает «и»: нужны оба условия. || означает включающее «или»: достаточно одного, а оба истинных тоже подходят. В коде это два знака |, без пробела между ними. Для нашего правила сначала получаем !done, затем проверяем группу в скобках. По приоритету ! выполняется раньше сравнений, сравнения — раньше &&, а && — раньше ||; скобки явно показывают намерение. Не заменяйте && на одиночный &: у него другой смысл.

a b a && b a || b
false false false false
false true false true
true false false true
true true true true

Короткое замыкание

Короткое замыкание — правая часть логического выражения вычисляется только при необходимости. У && она не выполняется, если слева false; у || — если слева true. Как охранник: если пропуска нет, проверять номер кабинета незачем. Граница образа: Rust следует точному порядку слева направо, а не догадывается, что опасно.

slots — число доступных мест, tasks — число задач, fits — результат проверки. При нуле мест slots != 0 ложно: деление вообще не выполняется. Если переставить части, получится попытка деления на ноль. Эта защита работает только для правильно записанного выражения.

Типичная ошибка

Число не становится логическим значением автоматически. Этот отдельный пример намеренно не компилируется: E0308 означает несовпадение типов.

fn main() {
    let ready: bool = 1;
    println!("{ready}");
}

Исправление зависит от замысла: задайте true или вычислите сравнение, например minutes > 0, когда minutes уже объявлено. Не подставляйте случайный тип ради исчезновения ошибки.

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

Данные → сравнения → bool → сочетание условий → проверка границ.

Проверьте понимание

  1. Чем = отличается от ==?
  2. Предскажите false || true и !true.
  3. Выполнится ли деление при slots = 0? Почему?

Сверка: присваивание и сравнение; true и false; деление пропускается благодаря левой части &&.

Задание

Обязательное. Показывайте задачу, только если она не выполнена, не архивирована и занимает не более 15 минут. Объявите done = false, archived = false, minutes: u32 = 15. Получите «Показать: true». Проверьте отдельно: done = true; archived = true; minutes = 16 — каждый случай должен дать false. Перед каждой проверкой верните остальные значения к исходным.

Проверьте границу. 15 минут подходят, 16 — нет. Объясните, почему здесь нужен <=, а не <.

Подсказка

Переведите каждую часть правила отдельно: «не» → !, «все одновременно» → &&. Ниже ответ для исходного случая; изменённые данные проверяйте сами.

Эталон после самостоятельной попытки

fn main() {
    let done: bool = false;
    let archived: bool = false;
    let minutes: u32 = 15;
    let show = !done && !archived && minutes <= 15;
    println!("Показать: {show}");
}
Показать: true

Источник для проверки

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

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

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

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