Functions in Rust: a good introduction
Tags: beginners, programming, tutorial, rust
Published: 2024-01-30 14:02:56

# Functions in Rust

In this 4th lesson, we will learn about functions in Rust.

If you prefer a video version
{% youtube hJLc2Zu405A %}

<!-- <iframe width="905" height="510" src="https://www.youtube.com/embed/hJLc2Zu405A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> -->

## What is a function?

A function is a set of statements that performs a task.

Functions are used to organize code into logical blocks, making it easier to read and maintain.

Functions are also used to avoid code duplication.

## Basics

we know that the main function is essential in every Rust program. For instance:

```rust
fn main() {
    println!("Hello, world!");
}
```

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ybx8c3yj9vuozc8bggc2.png)](https://youtu.be/hJLc2Zu405A)

Let's declare another_function and call it from main. 

We use the snake_case naming convention for functions.

```rust
fn main() {
    println!("Hello, world!");
    another_function();
}

fn another_function() {
    println!("another function in snake_case");
}
```

Will it compile? 

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oay83w7buh7ph2vctej0.png)](https://youtu.be/hJLc2Zu405A)

Yes, in Rust, the order of function declarations is not important, allowing flexibility in organizing code.

## Parameters

Parameters are special variables part of the function's signature, used to pass data to the function.

Although the terms parameters and arguments are often used interchangeably, technically, parameters refer to the variables in the function's definition, while arguments are the concrete values passed to the function.

Let's add a parameter to our function:

```rust
fn main() {
    another_function(42);
}

fn another_function(num) {
    println!("The values is, {}!", num);
}
```

Will it compile?

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7914qjomkt9f1jy9rfav.png)](https://youtu.be/hJLc2Zu405A)


No. This is because Rust is a statically typed language. This means that the compiler must know the type of every variable at compile time.

Here, the compiler doesn't know the type and it cannot infer it from the function body.

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.

```rust
fn main() {
    function2(42);
}

fn function2(num: i32) {
    println!("The values is, {}!", num);
}

```

Will it compile? 

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pho1fbkgbikcpo3ic52j.png)](https://youtu.be/hJLc2Zu405A)

Yes. Now the compiler knows that `num` is an `i32`.

## Multiple Parameters

When defining multiple parameters, you must separate them with a comma.

```rust
fn main() {
    function2(42, 'a');
}

fn function2(num: i32, letter: char) {
    println!("The values are, {} and {}!", num, letter);
}
```

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6mj36duijxt13zxlgf5m.png)](https://youtu.be/hJLc2Zu405A)

## Statements and Expressions

Understanding the difference between statements and expressions is crucial in Rust:

Statements are instructions that perform some action but do not return a value.

Expressions evaluate to a resulting value.

In Rust, functions can be considered as expressions, meaning they evaluate to a value.

For example, creating a variable is a statement, as it does not return a value:

```rust
fn main() {
    let x = 42;
}
```

Can we do this?

```rust
fn main() {
    let x = (let y = 42);
}
```

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqg0vpoeg7hqy9br5ecy.png)](https://youtu.be/hJLc2Zu405A)

No, because `let y = 42` is a statement and statements cannot be used as expressions.

Note that this would be valid in other languages, such as C, where the assignment operator returns the value assigned.

Expressions can be used as statements, but they will not return a value.

```rust
fn main() {
    let x = 5;
    let y = 6;
    let z = x + y;
}
```

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7px4zot1jfq8jf5zkrd.png)](https://youtu.be/hJLc2Zu405A)

- Calling a function is an expression.
- Calling a macro is an expression.
- A new scope block created with curly brackets is an expression, for example:

```rust
fn main() {
  let y = {
    let x = 3;
    x + 1
  };

  println!("The value of y is: {y}");
}
```

This block evaluates to 4, which is then assigned to y.
Note the absence of a semicolon in the last expression of the block.

## Return Values

Functions can return values to the code that calls them.
We don't name return values, but we do declare their type after an arrow (`->`).

Example:

```rust
fn sum() -> i32 {
    1 + 2
}

fn main() {
    let x = sum();
    println!("The value of x is: {x}");
}
```

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drp8wwjwhx4075mww6hk.png)](https://youtu.be/hJLc2Zu405A)


This works because the last expression in the function is `1 + 2`, which evaluates to 3, and 3 is returned from the function.

```rust
fn sum(num1:i32, num2:i32) -> i32 {
    num1 + num2
}

fn main() {
    let x = sum(5, 7);
    println!("The value of x is: {x}");
}
```

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nsxeapzx38e6upvn4ho.png)](https://youtu.be/hJLc2Zu405A)

We can return multiple values by separating them with a comma, and the return type must be a tuple:

```rust
//Return values in functions
fn sum_diff(num1:i32, num2:i32) -> (i32, i32) {
    (num1 + num2, num1 - num2)
}

fn main() {
    let x = sum_diff(10,8);
    println!("Sum and Diff is {:?}", x);
}

```

In this case, we return a tuple containing the sum and the difference of the two numbers.

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohwko1kb4znebzjf3i84.png)](https://youtu.be/hJLc2Zu405A)

The {:?} is a debug print

## Early Returns

Functions can return early with the `return` keyword.

```rust
//Return values in functions
fn sum_diff(num1:i32, num2:i32) -> (i32, i32) {
    return (num1 + num2, num1 - num2);
}

fn main() {
    let x = sum_diff(10,8);
    println!("Sum and Diff is {:?}", x);
}
```

Functions can return early with the `return` keyword.

```rust
//Return values in functions
fn sum_diff(num1:i32, num2:i32) -> (i32, i32) {
    return (num1 + num2, num1 - num2);
    println!("This line will not be executed");
}

fn main() {
    let x = sum_diff(10,8);
    println!("Sum and Diff is {:?}", x);
}
```

[![functions in Rust - Rust programming tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/synrr84z8gw0xlhzgdhc.png)](https://youtu.be/hJLc2Zu405A)

in this case, the last line in the sum_diff function will not be executed.

## Recap

To make a recap:

- they use the `fn` keyword
- they are snake_case
- they can be declared anywhere
- they can be declared with or without parameters
- they can return only one type, but it can be any type, including compund and custom types
- they can return early with the `return` keyword

If you prefer a video version
{% youtube hJLc2Zu405A %}

<!-- <iframe width="905" height="510" src="https://www.youtube.com/embed/hJLc2Zu405A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> -->

You can find me here: [Francesco Ciulla](https://www.francescociulla.com)