Skip to main content

Loops & Basic Logic Flows

This section will cover two foundational parts of Rust and programming in general: loops and logic flow.

Basic Logic Flows

Logic flows, sometimes called control flows, allow for conditional statements, such as if, to be possible. It allows for branching logic to be implemented for a program based on boolean values.

Using if

As said before, implementing logic based on whether something is true or not would be very useful if statements are the cornerstone of conditional logic.

let this_is_true: bool = true;

if this_is_true {
println!("Less trust, more truth!");
}

The above code showcases a very simple example. The statement this_is_true is set to a boolean value, true, which will execute the code within the brackets when evaluated by the if statement.

It's also possible to use an exclamation mark (!) to further diverge logic:

let this_is_true: bool = true;
if !this_is_true {
println!("Less trust, more truth!");
}

This no longer prints, as it looks for the opposite of true - false.

A more realistic example is checking if a number is higher or lower than expected, like seeing if a bank balance is over $100.

let bank_balance = 101;
if bank_balance >= 100 {
println!("More than 100 dollars");
}

Using else if and else

A single if statement can only be used so much. Using else if, we can create branches of logic within a program:

let bank_balance = 56;

if bank_balance >= 100 {
println!("More than, equal to, 100 dollars");
} else if bank_balance % 2 == 0 {
println!("You have an even balance!");
} else if bank_balance <= 0 {
println!("Uh oh, it appears you're in debt!");
} else {
println!("More than 0, but less than 100!");
}

Using match

You can also use a match statement to perform similar logic, which we will investigate later. A match statement is the most basic form of pattern matching:

let age = 18;

match age {
16 => println!("Old enough to drive"),
18 => println!("An adult"),
_ => println!("Irrelevant age")
}

Iterating with loops

Loops in Rust are very useful expressions, which, if you recall, produce a value as a result of some operation.

Although Rust supports five types of loops, we will go over the most common types:

  • The loop expression - an infinite loop which goes till break is called.
  • The while expression - a loop that continues until a condition is true or false.
  • The for expression - a loop that is useful for iterating over a collection of items.

Infinite loops: loop

Using the loop keyword, we can define an expression that iterates, or loops, infinitely:

fn main() {
loop {
println!("Print forever!");
}
}

This type of loop is typically used to keep trying some operation until a condition has been fulfilled.

Conditional loops: while

A while loop will automatically stop once a condition has been fulfilled. An example would be looping until a number has reached a certain limit:


fn main() {
let mut x = 0;
while (x <= 10) {
println!("x is now: {x}");
x += 1;
}
}

In this case, we define a mutable variable x. The while loop, which defines a condition while x is less than or equal to 10 (x <= 10), executes the logic until the condition for x is met.

A while loop could also iterate over a collection if needed:


fn main() {
let months = ["Jan", "Feb", "Mar", "Apr"];
let mut index = 0;
while (index <= months.len() - 1) {
println!("The month is now: {}", months[index]);
index += 1;
}
}

This is a bit clumsy, not to mention not friendly to any updates to the months array - an index could be out of bounds if we add or take away any elements from the array. Luckily, there is a better way to accomplish this.

Looping over collections: for

The for loop is primarily used for looping over a collection of items, such as an array. You may recall that we used a for loop to loop over several course modules.

Let's refactor the code from while to for:


fn main() {
let months = ["Jan", "Feb", "Mar", "Apr"];
for month in months{
println!("The month is now: {}", month);
}
}

Besides being much more concise, there is no worry about having an index out of bounds error.

Try it out!

What is happening here?

All the core loops are illustrated above. Notice the break keyword being used within loop, so the playground does not run infinitely (and so other loops can run!).