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

Логический тип в 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» — эта операция вызовет панику во время работы), а со значением, которое появляется только во время работы программы, она бы упала. Так что ставь «проверку безопасности» слева.

На аттракцион пускают, если рост не меньше 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
можно прокатиться: true
▶ Попробуй сам

Год високосный, если делится на 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 — високосный год: true
1900 — високосный год: false
▶ Попробуй сам
  • bool хранит ровно два значения: true или false.
  • Сравнения (==, <, >=, …) дают логические значения.
  • Условие в if должно быть настоящим bool — никаких неявных преобразований из чисел или строк.
  • && и || вычисляются по короткой схеме: они пропускают правую часть, как только ответ известен, поэтому проверки безопасности ставь слева.

Проверь себя

1. Значение какого типа даёт сравнение вроде age >= 18?

2. Можно ли в Rust использовать целое число вроде 0 прямо как условие в if, как в некоторых других языках?

3. Что произойдёт в count != 0 && total / count > 10, если count равно 0?

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