RustArena

Step 6 of 7

Booleans and logic

A bool has exactly two values, true and false. It's the answer to every yes/no question a program asks.

Comparisons produce bools

You'll use these constantly from the next modules on:

Operator Meaning
== equal (two = signs; a single = binds or assigns)
!= not equal
< and > less than, greater than
<= and >= less than or equal, greater than or equal
fn main() {
    let age = 17;
    let has_id = true;
    let is_adult = age >= 18;
    let is_seventeen = age == 17;
    let can_buy_ticket = age >= 16 && has_id;
    println!("adult: {is_adult}, seventeen: {is_seventeen}, can buy: {can_buy_ticket}");
}
adult: false, seventeen: true, can buy: true

age >= 16 && has_id combines two bools with && ("and"), one of the logic operators below.

Both sides of a comparison must have the same type: comparing an i32 with an f64 doesn't compile.

Logic operators

fn main() {
    let has_ticket = true;
    let is_vip = false;
    let banned = false;
    let can_enter = (has_ticket || is_vip) && !banned;
    println!("can enter: {can_enter}");
    println!("{} {} {}", true && false, true || false, !true);
}
can enter: true
false true false

&& binds tighter than ||, the way * binds tighter than +. Use parentheses to make your meaning obvious, as in can_enter above.

Short-circuiting

&& and || stop as soon as the answer is known. In a && b, if a is false, b is never evaluated. That lets the left side protect the right side:

fn main() {
    let count = 0;
    let total = 50;
    let busy = count != 0 && total / count > 10;
    println!("busy: {busy}");
}
busy: false

total / count would panic (division by zero), but it never runs because count != 0 is already false.

No "truthy" values

In some languages, 0 or empty text count as false. Rust has no such rule: where a bool is expected, only a bool will do. let ok: bool = 1; is a type error. Write the comparison you mean, like count != 0. If you ever need the number, true as i32 is 1.

Common mistakes

Chaining comparisons as in math doesn't work:

fn main() {
    let age = 15;
    let is_teen = 13 <= age <= 19;
    println!("{is_teen}");
}
error: comparison operators cannot be chained
 --> src/main.rs:3:22
  |
3 |     let is_teen = 13 <= age <= 19;
  |                      ^^     ^^
  |
help: split the comparison into two
  |
3 |     let is_teen = 13 <= age && age <= 19;
  |                             ++++++

Your task

A ride needs riders to be at least 120 cm tall, and riders under 16 must have an adult with them. Compute can_ride from the three variables (tall enough, and either 16 or older or with an adult) and print can ride: true.

Challenge 2

A login succeeds when the password is correct and the account is not locked. Fill in the operators so the program prints login ok: true.

Challenge 3

A year is a leap year if it's divisible by 4 and not by 100, or if it's divisible by 400. ("Divisible by 4" means year % 4 == 0.) For each of the three years in the starter code, compute a bool with this rule and print it:

2024: true
1900: false
2000: true

Writing the same rule three times is tedious; in the next module you'll write it once, as a function.

Previous: Converting types with as Next: Characters