Functions and Method Syntax
The library program keeps computing the same things: the late fee for a book, a short summary line for a catalogue entry. Functions give those calculations a name. Rust functions look plain, with one quiet rule about the last line that trips up every newcomer.
The rule
Types on every parameter; the last expression, with no semicolon, is returned.
fn late_fee(days: u32) -> u32 {
days * 10
}fnstarts a function; names usesnake_case.- Every parameter must have a type:
days: u32. Rust never guesses these. -> u32is the return type. Leave it out when nothing useful is returned.- The final expression
days * 10, with no semicolon, is the return value.returnexists for leaving early, but the last line normally needs no keyword.
Add a semicolon and days * 10; becomes a statement that produces nothing, written () and called "unit". The function then promises u32 but gives (), and the compiler rejects it.
Methods are functions attached to a type inside an impl block. Their first parameter is self in one of three forms:
struct Book { title: String, pages: u32 }
impl Book {
fn new(title: &str, pages: u32) -> Book { // associated function: no self
Book { title: title.to_string(), pages }
}
fn is_long(&self) -> bool { // reads the book
self.pages > 400
}
fn add_pages(&mut self, extra: u32) { // changes the book
self.pages += extra;
}
}
let mut book = Book::new("Iron Tides", 380);
book.add_pages(30);
println!("{}", book.is_long()); // true&self borrows to read, &mut self borrows to change, plain self takes the value over. Functions with no self, like new, are called on the type with ::.
The shortcut
Read any signature left to right as a sentence: "late_fee takes a u32 called days and gives back a u32." Then check the last line of the body gives exactly that type.
Read the signature
fn is_long(&self) -> bool: reads a book, gives back abool.
Drills
Answer fast — trust the rule.
What does fn double(n: i32) -> i32 { n * 2 } return for double(21)?
Why is fn total(a: u32, b: u32) -> u32 { a + b; } an error?
Which call is correct for fn new(title: &str, pages: u32) -> Book inside impl Book?
A method must change the book's page count but keep the book usable afterwards. Which first parameter fits?
Remember
- Parameters always carry types; the last expression, with no semicolon, is returned.
- Methods take
self,&selfor&mut selfand use a dot; associated functions useType::name. - Trap: a stray semicolon on the last line turns the result into
().
