Function Return Value

Function Return Value

Functions in Rust can return a value when they are called.

This adds a great deal of functionality and also helps to improve code efficiency because the return value can be used directly instead of having to store it in a variable.

This tutorial will cover the details and syntax for returning a value from a function, using the return keyword, and implicitly returning a value.

Returning a Value From a Function

In order to return a value from a function, we have to specify both the data type and the location of the return value.

The return data type must be specified following an arrow symbol ‘->‘ in the function definition. For example if we wanted to create a function called my_function that returns a 32 bit integer, we could write:

fn my_function() -> i32 {}

This would not compile as it is because we are telling Rust to expect a return value, but there’s nothing in the function body to be returned.

In the function body, we have to tell Rust what we want to be returned.

We can do this using the return keyword can be used or we simply let Rust implicitly return the value of the last line of code. We’ll go over both of these methods in turn:

Using the return Keyword

The classical way to have a function return a value is by using the return keyword. This keyword is used in the function body in order to specify what we want to be returned.

In the following example, we are using the return keyword so that the square() function returns the square (second power) of a number.

fn square(n: i32) -> i32 {
    return n * n;
}

let num = 3;
println!("The square is: {}", square(num));

Standard Output:

The square is: 9

There’s an even simpler way to have a function return a value in Rust: you can simply let it return the value of the last line of code.

Implicitly return a value

Rust doesn’t require use of the return keyword. If we simply leave the semicolon off the end of the last line of code, Rust will assume that we want its’ value to be returned.

For the last example, we could have just left out the return keyword and the semicolon:

fn square(n: i32) -> i32 {
    n * n
}

let num = 3;
println!("The square is: {}", square(num));

Standard Output:

The square is: 9

This will compile just fine and looks cleaner as well.

However, when we use return we aren’t limited to using the last line. This is a major limitation of implicitly returning a value when compared with using the return keyword.

What is Being Returned?

When we use either of these methods, we are telling Rust to return the value of a line of code that we are specifying.

The line of code, therefore, must be evaluable; i.e., able to be evaluated.

This is why it’s important that the value of the line of code must be of the same type that was specified in the definition. If we try to have a string returned when the compiler is expecting an integer, then the code will not compile properly.

Functions With Multiple Return Values

Rust allows us to return multiple values from a function using a tuple.

Tuples are a compound data type that can contain values of different types. This allows us to return multiple values from functions, using values of different types as needed.

To do this, we need to specify the types of each parameter in the tuple:

fn my_function() -> (type1, type2){}

In the following example, we create a function called circle() that calculates the area and circumference of a circle based on its’ radius.

These two values are returned as a tuple. The values of the tuple’s elements are then assigned to two new variables called area and circumference, and the values of each are printed to the console:

fn circle(r: f32) -> (f32, f32) {
    return (3.14*r*r, 6.28*r);
}

let radius: f32 = 3.0;
let (area, circumference) = circle(radius);
println!("The area is: {}", area);
println!("The circumference is: {}", circumference);