Control Flow
In this chapter, we'll explore make decisions and repeat code with if expressions and loops.
Control Flow
The ability to run code depending on conditions and to run code repeatedly while a condition is true are basic building blocks in most programming languages. The most common constructs for controlling execution flow are if expressions and loops.
if Expressions
An if expression allows you to branch your code depending on conditions:
module main
fn main() -> void {
let number = 3
if number < 5 {
println("condition was true")
} else {
println("condition was false")
}
}All if expressions start with if, followed by a condition. The block of code following the condition executes if the condition is true. Blocks associated with conditions are sometimes called arms.
Optionally, we can include an else expression for code to execute when the condition is false.
Handling Multiple Conditions with else if
Use else if for multiple conditions:
module main
fn main() -> void {
let number = 6
if number % 4 == 0 {
println("number is divisible by 4")
} else if number % 3 == 0 {
println("number is divisible by 3")
} else if number % 2 == 0 {
println("number is divisible by 2")
} else {
println("number is not divisible by 4, 3, or 2")
}
}Mana executes the first block whose condition evaluates to true and doesn't check the rest.
Using if in a let Statement
Because if is an expression, we can use it on the right side of a let statement:
module main
fn main() -> void {
let condition = true
let number = if condition { 5 } else { 6 }
println("The value of number is: ", number)
}The value of the whole if expression depends on which block executes. Both arms must have compatible types:
let number = if condition { 5 } else { "six" } // Error: incompatible typesRepetition with Loops
Mana has three kinds of loops: loop, while, and for.
Repeating Code with loop
The loop keyword creates an infinite loop:
module main
fn main() -> void {
loop {
println("again!")
}
}This prints again! forever until you manually stop the program.
Returning Values from Loops
You can return a value from a loop using break:
module main
fn main() -> void {
let mut counter = 0
let result = loop {
counter = counter + 1
if counter == 10 {
break counter * 2
}
}
println("The result is ", result) // 20
}Conditional Loops with while
A while loop runs while a condition is true:
module main
fn main() -> void {
let mut number = 3
while number != 0 {
println(number, "!")
number = number - 1
}
println("LIFTOFF!")
}This eliminates a lot of nesting compared to loop, if, else, and break.
Looping Through a Collection with for
Use for to loop over elements in a collection:
module main
fn main() -> void {
let a = [10, 20, 30, 40, 50]
for element in a {
println("the value is: ", element)
}
}The for loop is the most commonly used loop in Mana because it's safe (no chance of going past the array bounds) and concise.
Range Iteration
Use ranges to loop a specific number of times:
module main
fn main() -> void {
for number in 1..4 {
println(number, "!")
}
println("LIFTOFF!")
}Output:
1!
2!
3!
LIFTOFF!
For an inclusive range, use ..=:
for i in 1..=5 {
println(i) // 1, 2, 3, 4, 5
}To reverse:
for number in (1..4).rev() {
println(number, "!")
}
// Prints 3!, 2!, 1!Loop Control: break and continue
Use break to exit a loop and continue to skip to the next iteration:
for i in 0..10 {
if i == 3 {
continue // Skip 3
}
if i == 7 {
break // Stop at 7
}
println(i)
}
// Prints: 0, 1, 2, 4, 5, 6The match Expression
The match expression is a powerful control flow construct:
let x = 1
match x {
1 => println("one"),
2 => println("two"),
3 => println("three"),
_ => println("something else"),
}We'll explore match in depth in Chapter 6.
The defer Statement
Execute code when leaving a scope:
fn process_file(path: string) -> void {
let file = open(path)
defer file.close() // Runs when function exits
// Work with file...
// file.close() called automatically
}Multiple defers execute in reverse order (LIFO):
fn example() -> void {
defer println("first")
defer println("second")
defer println("third")
}
// Prints: third, second, firstSummary
You've learned about:
if/else if/elsefor conditional branching- Using
ifas an expression loopfor infinite loops with optional return valueswhilefor conditional loopsforfor iterating over collections and rangesbreakandcontinuefor loop controldeferfor cleanup code
These control flow constructs, combined with what you learned about Variables, Data Types, and Functions, let you write increasingly complex programs.
Next, we'll explore one of Mana's most unique features: Ownership.