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
a && b(and) is true when both are true.a || b(or) is true when at least one is true.!a(not) is true whenais false.
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;
| ++++++
=instead of==:=binds or assigns;==compares.&or|instead of&&and||: the single-character versions exist (they're bitwise operators) but don't short-circuit. Use the doubled ones for logic.
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.