What the and operator does
Often a decision depends on more than one fact. The logical and operator, written &&, joins two bool expressions and gives true only when both of them are true. If either side is false, the whole expression is false.
| left | right | left && right |
|---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
The operands are usually comparisons. For example, 10 == 10 && 7 < 10 is true: the left comparison is true, the right one is true, and so is the pair. Comparison operators bind tighter than &&, so no parentheses are needed around them.
Using it in an if
The typical use is as the condition of an if:
let x = 10;
if x != 7 && 12 < x {
println!("This is true!");
}
Here x != 7 is true because 10 is not 7, but 12 < x is false because 12 is not below 10. One false side makes the whole condition false, so the block is skipped and the program prints nothing.
In Rust, the condition of an if is written without parentheses, and the braces around the body are mandatory. The condition must also have the type bool. Rust does not treat numbers as true or false, so if x { ... } with an integer x is a compile error (expected `bool`, found integer).
The result is a value
An && expression is not tied to if. It produces a bool that you can store with let both = 7 < 10 && 10 == 10;, print with println!("{}", both), return from a function, or pass on to another condition. The if is simply the most common place to use one.
More than two conditions
Operators chain, so a && b && c is true only when all three are true. The pieces can also be stored in bool variables first. With let is_adult = age >= 18; and let has_ticket = true;, the condition is_adult && has_ticket reads almost like a sentence. Naming the parts is a good habit when a condition grows long.
Short-circuit evaluation
The right operand is evaluated only if the left one is true. When the left side is false, the answer is already known to be false, so Rust skips the right side. This is called short-circuiting. It matters when the right side has an effect or could fail. With a function that prints a message as it checks, check("a", false) && check("b", true) prints only checked a: the call for "b" never runs.
The same programs can use a single &. On two bool values it also computes "and", but it always evaluates both sides. The usual choice for conditions is &&.
Common mistakes
- Writing
and. Rust has noandkeyword. The compiler stops with`and` is not a logical operatorand suggests&&. - A single
&. It compiles on booleans but evaluates both sides, so it loses short-circuiting. On integers it means something else entirely, a bitwise and. - Repeating the variable. To check that
xis between 5 and 9, writex > 5 && x < 9. Both comparisons need the variable;x > 5 && < 9is not valid. - Chaining comparisons.
5 < x < 9is rejected by the compiler withcomparison operators cannot be chained.
The lesson's exercise
The exercise decides between going to the beach and learning to code. The beach needs both sunny weather and a high temperature.
- Declare
weatheras"rainy"andtemperatureas90withlet. Both bindings are immutable, which is fine because they never change. - Write an
ifwhose condition isweather == "sunny" && temperature > 85. Comparing two&strvalues with==compares their text. - Print
"Going to the beach"in theifblock withprintln!. - Add an
elsethat prints"Learning to code".
let weather = "rainy";
let temperature = 90;
if weather == "sunny" && temperature > 85 {
println!("Going to the beach");
} else {
println!("Learning to code");
}
The temperature is above 85, so that check passes, but the weather is not "sunny", so the and fails and the else runs. The program prints Learning to code. Change weather to "sunny" and it prints Going to the beach.
Key takeaways
a && bistrueonly if bothaandbaretrue.- The right side is skipped when the left side is
false. - Conditions must be
bool, are written without parentheses, and need braces around the body. - Rust spells the operator
&&, neverand.
