Skip to content

Rust Booleans

A boolean is the simplest type there is: it can only be true or false. In Rust it’s called bool, and you’ll use it everywhere you need to make a decision in your code.

fn main() {
let is_active = true;
let has_error: bool = false;
println!("active: {is_active}, error: {has_error}");
}
▶ Try it Yourself

Rust almost always infers bool on its own from true/false, so you rarely need to write the type explicitly.

You don’t often write true or false directly in real code — they usually come from comparing something:

fn main() {
let age = 20;
let can_vote = age >= 18;
println!("Can vote: {can_vote}");
}

Output:

Can vote: true
▶ Try it Yourself

The main job of a bool is deciding which branch of an if to run:

fn main() {
let is_raining = true;
if is_raining {
println!("Take an umbrella");
} else {
println!("Leave it at home");
}
}

We cover if properly on the If…Else page — this is just a taste of why booleans matter.

You met && (and), || (or) and ! (not) on the Operators page. There’s one more thing to know about them: they stop early when the answer is already decided. This is called short-circuit evaluation.

  • With a && b, if a is false, the whole thing must be false, so Rust never looks at b.
  • With a || b, if a is true, the whole thing must be true, so Rust never looks at b.

That’s more than a speed trick. It lets the left side protect the right side:

fn main() {
let count = 0;
let total = 50;
// count is 0, so Rust stops after `count != 0` and never divides.
let big_average = count != 0 && total / count > 10;
println!("big average: {big_average}");
let is_weekend = true;
let has_homework = true;
// is_weekend is true, so `!has_homework` is never checked.
let can_relax = is_weekend || !has_homework;
println!("can relax: {can_relax}");
}

Output:

big average: false
can relax: true
▶ Try it Yourself

Dividing by zero would crash the program. Because count != 0 comes first and is false, the division simply never runs. Swap the two sides (total / count > 10 && count != 0) and the division would run first. Here the compiler even spots it and refuses to build (“this operation will panic at runtime”); with a value that only arrives while the program runs, it would crash instead. So put the “safety check” on the left.

A theme park ride lets you on if you are at least 120 cm tall, or if you are at least 8 years old and riding with an adult. Store a height of 115, an age of 9 and with_adult = true, then print whether this child can ride. Hint: use parentheses to group the “age and adult” part.

Show solution
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: {tall_enough}");
println!("can ride: {can_ride}");
}

Output:

tall enough: false
can ride: true
▶ Try it Yourself

A year is a leap year if it divides by 4 but not by 100, or if it divides by 400. Work out a boolean is_leap for 2024, print it, then do the same for 1900. Hint: “divides by 4” is year % 4 == 0, and you can shadow year and is_leap with a second let.

Show solution
fn main() {
let year = 2024;
let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
println!("{year} is a leap year: {is_leap}");
let year = 1900;
let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
println!("{year} is a leap year: {is_leap}");
}

Output:

2024 is a leap year: true
1900 is a leap year: false
▶ Try it Yourself
  • bool holds exactly two values: true or false.
  • Comparisons (==, <, >=, …) produce booleans.
  • Conditions in if must be a real bool — no implicit conversions from numbers or strings.
  • && and || short-circuit: they skip the right side once the answer is known, so put safety checks on the left.

Quick check

1. What type does a comparison like age >= 18 produce?

2. In Rust, can you use an integer like 0 directly as a condition in an if, the way you might in some other languages?

3. In count != 0 && total / count > 10, what happens when count is 0?

Score: 0 / 3