Rust lang notes - Functions and flow control
Functions
Functions are defined using the fn
keyword, followed by whatever name you want to give your function.
fn next_birthday( name: &str, current_age: u8 ) {
let next_age = current_age + 1;
println!("Hi {}, on your next birthday you'll be {}!", name, next_age );
}
Within parentheses, list each parameter the function takes by giving the parameter name, then a colon, then specifying the type of that parameter. Separate each name/type pair with a comma.
If the function returns a value, put an arrow ( ->
), and then specify the type of the return value. If the function doesn't return a value, leave off the arrow and the return type.
Then, open a set of curly brackets, put the code you want to be the body of the function, and close the curly brackets.
There are more complicated function signatures possible, way more complicated!!
Also, there is a return
keyword that you can use to return from a function early, and you can use it at the end of a function if you want. However, idiomatic style is to implicitly return the last expression.
fn next_age( current_age: u8 ) -> u8 {
current_age + 1
}
If the last line in the body doesn't have a semicolon at the end. This tells Rust we want the resulting value of that expression returned out of the function body.
Control Flow
if / else if / else
if expression {
...code...
} else if expression {
...code...
} else {
...code...
}
Like with functions, we can get a value from an if or else block by leaving the semicolon off of the last expression in the block.
let amount = if day_number % 2 == 0 {
10
} else {
20
};
Return from if else expression have some restrictions
- We do need a semicolon to end the variable assignment statement.
- There must be an else clause so that the variable always gets a value.
- The types of the values must all be the same
loop, while, for
The loop
keyword lets you specify a block of code that should be run forever.
loop {
println!("Hello, notes!");
}
You can use the break
keyword to exit a loop.
A while
loop is written with the while
keyword, then an expression that evaluates to true
or false
while expression {
...code...
}
The code in the block runs over and over, while the expression specified is true.
The for
loop is probably the most common loop in Rust code. It lets you run some code for each item in a collection. Unlike for loops in some other languages, like C, you don't need to manage an index into the collection and worry about off-by-one errors.
for item in collection {
...code...
}
match
It's sort of like a bunch of if/else
ifs and sort of like a switch
or case
statement, but better for two reasons:
- pattern matching
Pattern matching is a feature available in Rust in multiple places. For example, destructured a tuple into parts in the Data types module.
let tup = ( 1, 'a', true );
let (a,b,c) = tup;
Is especially useful in match expressions. We specify a list of patterns to test a value against, and the match expression tests the value against each pattern and stops if it finds a matching one.
let x = 4;
match x {
1 => println!("Uno"),
2 => println!("Dos"),
3 => println!("Tres"),
_ => println!("Rest of the numbers...")
}
The underscore in the last pattern is a catch-all that will match any value. So the last arm functions like an else in a set of if/elseif/else blocks.
- exhaustiveness
Must be exhaustive and cover every case. This prevents bugs that can be caused by forgetting to handle a situation.
Book chapters Functions / Control flow