Control Flow
The ability to run some code depending on whether a condition is true
and to run some code repeatedly while a condition is true
are basic building blocks in most programming languages.
If Else
fn main() {
let a = 58;
if a < 0 {
print!("{} is negative", a);
} else if a > 0 {
print!("{} is positive", a);
} else {
print!("{} is zero", a);
}
}
Loop
Rust provides a loop
keyword to indicate an infinite loop. Similar to other C-like languages, the break
statement can be used to exit a loop at anytime, whereas the continue
statement can be used to skip the rest of the iteration and start a new one.
fn main() {
let mut count = 0;
loop {
count += 1;
if count == 7 {
println!("seven");
continue;
}
println!("{}", count);
if count == 10 {
println!("Let's end here!");
break;
}
}
}
Loop Labels
You may annotate the loops with some 'label
. In that case, you can break
or continue
outer loops when the label is passed to the statement.
fn main() {
'outer: loop {
println!("The outer loop begins");
'inner: loop {
println!("The inner loop begins");
break 'outer;
}
println!("Unreachable line here");
}
println!("The outer loop ends");
}
Return from the loop
You can put the return value after the break
, and it will be returned by the loop
expression.
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("counter: {} result: {}", counter, result);
// counter: 10 result: 20
}
While
fn main() {
let mut n = 1;
while n < 10 {
if n % 2 == 0 {
println!("{}", n);
}
n += 1;
}
}
For
The a..b
notation can create a range
in Rust.
The for ... in
construct can be used to iterate through a range, or more generally, an Iterator
.
fn main() {
for n in 1..5 {
print!("{} ", n); // 1 2 3 4
}
}
If you want to include the end element of the range, use a..=b
notation.
fn main() {
for n in 1..=5 {
print!("{} ", n); // 1 2 3 4 5
}
}
iter
, iter_mut
and into_iter
all convert a collection into an iterator in different ways.
fn main() {
let names = vec!["Alice", "Bob", "Cindy"];
for name in names.iter() {
print!("{} ", name)
}
println!("\nnames: {:?}", names);
// Alice Bob Cindy
// names: ["Alice", "Bob", "Cindy"]
}
Match
The pattern matching can be used like a C switch
, but it can do even more.
fn main() {
let number = 7;
match number {
1 => println!("One"),
2 | 3 | 5 | 7 | 11 => println!("A prime"),
13..=19 => println!("A teen"),
_ => println!("Others"),
}
}
Destructuring
A match
block can destructure items(tuples, arrays, enums, structs and etc) in a variety of ways.
fn main() {
let triple = (5, -8, 2);
match triple {
(0, y, z) => println!("First is `0`, `y` is {:?}, and `z` is {:?}", y, z),
(1, ..) => println!("First is `1` and the rest doesn't matter"),
(.., 2) => println!("last is `2` and the rest doesn't matter"),
_ => println!("It doesn't matter what they are"),
}
// last is `2` and the rest doesn't matter
}
enum Color {
Red,
RGB(u16, u16, u16),
CMYK(u32, u32, u32, u32),
}
fn main() {
let color = Color::RGB(58, 23, 78);
match color {
Color::Red => println!("The color is Red!"),
Color::RGB(r, g, b) =>
println!(
"Red: {}, green: {}, and blue: {}", r, g, b),
Color::CMYK(c, m, y, k) =>
println!(
"Cyan: {}, magenta: {}, yellow: {}, key (black): {}!",
c, m, y, k),
}
// Red: 58, green: 23, and blue: 78
}
Guard
A guard can be added to filter the match arm.
fn main() {
let a: u8 = 58;
match a {
i if i == 0 => println!("Zero"),
i if i > 0 => println!("Greater than zero"),
_ => unreachable!("Should never happen."),
}
// Greater than zero
}
Binding
match
provides the @
sigil to bind values to names, so you can use the matched item as a variable inside the arm.
fn main() {
let number = 11;
match number {
1 => println!("One"),
n @ (2 | 3 | 5 | 7 | 11) => println!("A prime: {}", n),
13..=19 => println!("A teen"),
_ => println!("Others"),
}
// A prime: 11
}
If Let
For some use cases, when matching enums, match
is kind of cumbersome.
let a = Some(58);
match a {
Some(b) => {
println!("My precious value is {}", b);
},
_ => {},
}
if let
comes to the save for this use case.
if let Some(b) = a {
println!("My value is {}", b);
}
While Let
while let
can handle similar use cases.
fn main() {
let mut optional = Some(0);
while let Some(i) = optional {
if i > 9 {
println!("Hit 9, quit!");
optional = None;
} else {
println!("It's {}, try again.", i);
optional = Some(i + 1);
}
}
}
// It's 0, try again.
// It's 1, try again.
// It's 2, try again.
// It's 3, try again.
// It's 4, try again.
// It's 5, try again.
// It's 6, try again.
// It's 7, try again.
// It's 8, try again.
// It's 9, try again.
// Hit 9, quit!
Code Challenge
Try to modify the code provided in the editor to make it print
Greeting from John: John
.