Skip to main content

Functions

  • Declare function using fn, reference: https://doc.rust-lang.org/std/primitive.fn.html
  • Rust code uses snake case as the conventional style for function and variable names.
  • In function signatures, you must declare the type of each parameter.
  • When defining multiple parameters, separate the parameter declarations with commas.
  • Functions can return values to the code that calls them. We don’t name return values, but we must declare their type after an arrow ->.
  • Rust have statements and expressions:
    • Statements are instructions that perform some action and do not return a value.
    • Expressions evaluate to a resultant value. Let’s look at some examples.
    • If you add a semicolon to the end of an expression, you turn it into a statement, and it will then not return a value.
  • You can return early from a function by using the return keyword and specifying a value, but most functions return the last expression implicitly.
  • Reference: Functions

functions1.rs

// Add some function with the name `call_me` without arguments or a return value.
fn call_me() {
println!("called")
}

fn main() {
call_me(); // Don't change this line
}

functions2.rs

// Add the missing type of the argument `num` after the colon `:`.
// Lets use i32 for the argument tyoe.
fn call_me(num: i32) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}
}

fn main() {
call_me(3);
}
  • In function signatures, you must declare the type of each parameter.

    This is a deliberate decision in Rust’s design: requiring type annotations in function definitions means the compiler almost never needs you to use them elsewhere in the code to figure out what type you mean. The compiler is also able to give more helpful error messages if it knows what types the function expects.

  • When defining multiple parameters, separate the parameter declarations with commas.

  • So we just need to add i32 as the arguments/parameter type.

functions3.rs

fn call_me(num: u8) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}
}

fn main() {
// Add parameters to call_me function.
call_me(5);
}
  • call_me function expect an argument/parameter, add 5 as parameter since the function expect type u8.

functions4.rs

// This store is having a sale where if the price is an even number, you get 10
// Rustbucks off, but if it's an odd number, it's 3 Rustbucks off.
// Don't worry about the function bodies themselves, we are only interested in
// the signatures for now.

fn is_even(num: i64) -> bool {
num % 2 == 0
}

//
fn sale_price(price: i64) -> i64 {
if is_even(price) {
price - 10
} else {
price - 3
}
}

fn main() {
let original_price = 51;
println!("Your sale price is {}", sale_price(original_price));
}
  • Functions can return values to the code that calls them. We don’t name return values, but we must declare their type after an arrow ->.
  • In this exercise we just need to add return type as i64.

functions5.rs

// Remove the semicolon to make it as expression
fn square(num: i32) -> i32 {
num * num
}

fn main() {
let answer = square(3);
println!("The square of 3 is {answer}");
}
  • Rust have statements and expressions:
    • Statements are instructions that perform some action and do not return a value.
    • Expressions evaluate to a resultant value. Let’s look at some examples.
    • If you add a semicolon to the end of an expression, you turn it into a statement, and it will then not return a value.
  • You can return early from a function by using the return keyword and specifying a value, but most functions return the last expression implicitly.
  • In this exercise the square functions expect a return value, but the function body only have one line statement. By removing the semicolon ; we make it as an expression and will return the value of num * num