Rust Function Return Values

What are Function Return Values?

A return value is the data a function produces and hands back to the caller after completing its task. In Rust, functions can return values of any type, and the return type must be explicitly declared. Rust’s type system ensures that return values are used safely and predictably.

Syntax for Function Return Values

The syntax for returning a value from a function involves:

  1. Declaring the return type after an arrow -> in the function signature.
  2. Using an expression (without a semicolon) or the return keyword to specify what the function returns.
fn function_name() -> return_type {
// Function body
value // or return value;
}

Examples of Function Return Values

Example 1: Returning a Single Value

fn square(num: i32) -> i32 {
num * num // Implicit return
}

fn main() {
let result = square(4);
println!("The square of 4 is: {}", result);
}

Output:

The square of 4 is: 16

Here:

  • The function square returns the result of num * num.
  • The return type i32 is explicitly declared in the function signature.

Example 2: Using return Keyword

fn cube(num: i32) -> i32 {
return num * num * num; // Explicit return
}

fn main() {
let result = cube(3);
println!("The cube of 3 is: {}", result);
}

Output:

The cube of 3 is: 27

In this example, the return keyword explicitly specifies the value to be returned.

Returning Multiple Values

Rust functions can return multiple values using tuples. This is useful when you need to return related values together.

Example 3: Returning Multiple Values

fn calculate(a: i32, b: i32) -> (i32, i32) {
(a + b, a * b) // Returns a tuple
}

fn main() {
let (sum, product) = calculate(5, 3);
println!("Sum: {}, Product: {}", sum, product);
}

Output:

Sum: 8, Product: 15

The function calculate returns a tuple containing the sum and product of two numbers.

Returning Early with return

You can use the return keyword to exit a function early, even before reaching the end of the function body.

Example 4: Early Return

fn check_even(num: i32) -> bool {
if num % 2 == 0 {
return true; // Early return
}
false // Default return
}

fn main() {
let result = check_even(10);
println!("Is 10 even? {}", result);
}

Output:

Is 10 even? true

Functions Without Return Values

If a function does not return a value, it has the return type ( ), also known as the “unit type.” Such functions are used for performing actions rather than producing a value.

Example 5: Void Function

fn print_message() {
println!("This function does not return a value.");
}

fn main() {
print_message();
}

Output:

This function does not return a value.

Using Option and Result as Return Types

Rust’s standard library provides Option and Result types for handling cases where a function might not return a valid value or could fail.

Example 6: Returning an Option

fn divide(a: i32, b: i32) -> Option<i32> {
if b == 0 {
None // Return None for invalid division
} else {
Some(a / b) // Return Some(value) for valid division
}
}

fn main() {
match divide(10, 2) {
Some(result) => println!("Result: {}", result),
None => println!("Cannot divide by zero"),
}
}

Output:

Result: 5

Example 7: Returning a Result

fn safe_divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
Err(String::from("Division by zero")) // Error case
} else {
Ok(a / b) // Success case
}
}

fn main() {
match safe_divide(10, 0) {
Ok(result) => println!("Result: {}", result),
Err(e) => println!("Error: {}", e),
}
}

Output:

Error: Division by zero

Returning References

Rust functions can return references. However, this requires proper handling of lifetimes to ensure memory safety.

Example 8: Returning References

fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
if s1.len() > s2.len() {
s1
} else {
s2
}
}

fn main() {
let str1 = "Rust";
let str2 = "Programming";
let result = longest(str1, str2);
println!("The longest string is: {}", result);
}

Output:

The longest string is: Programming

Leave a Comment

BoxofLearn