Логический тип в Rust
Логическое значение (boolean) — самый простой тип, какой только бывает: оно может быть только true или false. В Rust этот тип называется bool, и он нужен везде, где код должен принять решение.
Объявляем логическую переменную
Заголовок раздела «Объявляем логическую переменную»fn main() { let is_active = true; let has_error: bool = false; println!("активно: {is_active}, ошибка: {has_error}");}Rust почти всегда сам понимает, что true/false — это bool, поэтому явно указывать тип приходится редко.
Логические значения обычно получаются из сравнений
Заголовок раздела «Логические значения обычно получаются из сравнений»В настоящем коде true или false редко пишут напрямую — обычно они получаются в результате сравнения:
fn main() { let age = 20; let can_vote = age >= 18; println!("Может голосовать: {can_vote}");}Вывод:
Может голосовать: trueЛогические значения в условиях
Заголовок раздела «Логические значения в условиях»Главная работа bool — решать, какую ветку if выполнить:
fn main() { let is_raining = true;
if is_raining { println!("Возьми зонт"); } else { println!("Оставь его дома"); }}Как следует if разобран в уроке If…Else — здесь лишь небольшой пример того, зачем нужны логические значения.
Объединение условий и короткая схема вычисления
Заголовок раздела «Объединение условий и короткая схема вычисления»С && (и), || (или) и ! (не) ты познакомился в уроке Операторы. Про них нужно знать ещё одно: они останавливаются раньше, когда ответ уже понятен. Это называется вычислением по короткой схеме (short-circuit evaluation).
- В
a && b, еслиaравноfalse, всё выражение точноfalse, поэтому Rust даже не смотрит наb. - В
a || b, еслиaравноtrue, всё выражение точноtrue, поэтому Rust даже не смотрит наb.
Это не просто способ ускорить код. Так левая часть может защищать правую:
fn main() { let count = 0; let total = 50;
// count равно 0, поэтому Rust останавливается после `count != 0` и не делит. let big_average = count != 0 && total / count > 10; println!("большое среднее: {big_average}");
let is_weekend = true; let has_homework = true; // is_weekend равно true, поэтому `!has_homework` вообще не проверяется. let can_relax = is_weekend || !has_homework; println!("можно отдохнуть: {can_relax}");}Вывод:
большое среднее: falseможно отдохнуть: trueДеление на ноль обрушило бы программу. Но count != 0 стоит первым и равно false, поэтому деление просто не выполняется. Если поменять части местами (total / count > 10 && count != 0), деление выполнится первым. Здесь компилятор даже заметит это и откажется собирать программу («this operation will panic at runtime» — эта операция вызовет панику во время работы), а со значением, которое появляется только во время работы программы, она бы упала. Так что ставь «проверку безопасности» слева.
Практика
Заголовок раздела «Практика»1. Пустят ли на аттракцион?
Заголовок раздела «1. Пустят ли на аттракцион?»На аттракцион пускают, если рост не меньше 120 см, или если тебе не меньше 8 лет и ты катаешься со взрослым. Сохрани рост 115, возраст 9 и with_adult = true, а затем выведи, может ли ребёнок прокатиться. Подсказка: сгруппируй скобками часть «возраст и взрослый».
Показать решение
fn main() { let height_cm = 115; let age = 9; let with_adult = true;
let tall_enough = height_cm >= 120; let can_ride = tall_enough || (age >= 8 && with_adult);
println!("достаточно высокий: {tall_enough}"); println!("можно прокатиться: {can_ride}");}Вывод:
достаточно высокий: falseможно прокатиться: true2. Високосные годы
Заголовок раздела «2. Високосные годы»Год високосный, если делится на 4, но не делится на 100, или если делится на 400. Вычисли логическое значение is_leap для 2024, выведи его, а затем сделай то же для 1900. Подсказка: «делится на 4» — это year % 4 == 0, а year и is_leap можно затенить вторым let.
Показать решение
fn main() { let year = 2024; let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; println!("{year} — високосный год: {is_leap}");
let year = 1900; let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; println!("{year} — високосный год: {is_leap}");}Вывод:
2024 — високосный год: true1900 — високосный год: falseboolхранит ровно два значения:trueилиfalse.- Сравнения (
==,<,>=, …) дают логические значения. - Условие в
ifдолжно быть настоящимbool— никаких неявных преобразований из чисел или строк. &&и||вычисляются по короткой схеме: они пропускают правую часть, как только ответ известен, поэтому проверки безопасности ставь слева.
Проверь себя
Заголовок раздела «Проверь себя»Проверь себя
1. Значение какого типа даёт сравнение вроде age >= 18?
2. Можно ли в Rust использовать целое число вроде 0 прямо как условие в if, как в некоторых других языках?
3. Что произойдёт в count != 0 && total / count > 10, если count равно 0?
Результат: 0 / 3
Что почитать
Заголовок раздела «Что почитать»- Логический тип данных — книга «Язык программирования Rust»: официальное короткое знакомство с
boolрядом с другими базовыми типами (перевод на русский). bool— документация стандартной библиотеки (на английском): все методыbool, напримерthenиthen_some, — когда будешь к ним готов.- Lazy boolean operators — The Rust Reference (на английском): точные правила того, как
&&и||пропускают правую часть. - Примитивы — Rust на примерах:
boolрядом с другими встроенными типами Rust, с примером, который можно запустить (перевод на русский).