Control Flow
Control Flow primitives
ifexpressionsloopandwhileloopsmatchexpressionsforloopsbreakandcontinuereturnand?
Using if as a statement
- Tests if a boolean expression is
true - Parentheses around the conditional are not necessary
- Blocks need brackets, no shorthand
fn main() {
if 1 == 2 {
println!("integers are broken");
} else if 'a' == 'b' {
println!("characters are broken");
} else {
println!("that's what I thought");
}
}
Using if as an expression
- Every block is an expression
- Note the final
;to terminate theletstatement.
fn main() {
let x = if 1 == 2 {
100
} else if 'a' == 'b' {
200
} else {
300
};
}
Using if as the final expression
Now the if expression is the result of the function:
#![allow(unused)]
fn main() {
fn some_function() -> i32 {
if 1 == 2 {
100
} else if 'a' == 'b' {
200
} else {
300
}
}
}
Looping with loop
loop is used for (potentially) infinite loops
fn main() {
let mut i = 0;
loop {
i += 1;
if i > 100 { break; }
}
}
Looping with loop
loop blocks are also expressions…
fn main() {
let mut i = 0;
let loop_result = loop {
i += 1;
if i > 10 { break 6; }
println!("i = {}", i);
};
println!("loop_result = {}", loop_result);
}
while
whileis used for conditional loops.- Loops while the boolean expression is
true
fn main() {
let mut i = 0;
while i < 10 {
i += 1;
println!("i = {}", i);
}
}
Control Flow with match
- The
matchkeyword does pattern matching - You can use it a bit like an
if/else if/elseexpression - The first arm to match, wins
_means match anything
fn main() {
let a = 4;
match a % 3 {
0 => { println!("divisible by 3") }
_ => { println!("not divisible by 3") }
}
}
for loops
foris used for iteration- Here
0..10creates aRange, which you can iterate
fn main() {
for num in 0..10 {
println!("{}", num);
}
}
for loops
Lots of things are iterable
fn main() {
for ch in "Hello".chars() {
println!("{}", ch);
}
}
for under the hood
- What Rust actually does is more like…
- (More on this in the section on Iterators)
fn main() {
let mut iter = "Hello".chars().into_iter();
loop {
match iter.next() {
Some(ch) => println!("{}", ch),
None => break,
}
}
}
Break labels
If you have nested loops, you can label them to indicate which one you want to break out of.
fn main() {
'cols: for x in 0..5 {
'rows: for y in 0..5 {
println!("x = {}, y = {}", x, y);
if x + y >= 6 {
break 'cols;
}
}
}
}
Continue
Means go around the loop again, rather than break out of the loop
fn main() {
'cols: for x in 0..5 {
'rows: for y in 0..5 {
println!("x = {}, y = {}", x, y);
if x + y >= 4 {
continue 'cols;
}
}
}
}
return
returncan be used for early returns- The result of the last expression of a function is always returned
#![allow(unused)]
fn main() {
fn get_number(x: bool) -> i32 {
if x {
return 42;
}
-1
}
}