techmore.in

Rust - Functions

Functions in Rust are a fundamental building block of the language, used to encapsulate reusable code into distinct units. Here's a detailed overview of how to define and use functions in Rust:

Defining Functions

A function is defined using the fn keyword, followed by the function name, parameters, and the function body. The function's return type, if any, is specified after an arrow (->).

Basic Function

rust
fn main() { greet(); // Calling the function } fn greet() { println!("Hello, world!"); }

In this example, greet is a function that prints a message to the console. It doesn’t take any parameters and doesn’t return any value.

Functions with Parameters

Functions can take parameters, which are variables passed into the function.

Function with Parameters

rust
fn main() { let name = "Alice"; greet(name); } fn greet(name: &str) { println!("Hello, {}!", name); }

In this example, the greet function takes a single parameter name of type &str (string slice) and prints a personalized message.

Returning Values

Functions can return values using the -> syntax. The return type comes after the -> symbol.

Function Returning a Value

rust
fn main() { let result = add(5, 3); println!("The sum is: {}", result); } fn add(a: i32, b: i32) -> i32 { a + b // The return value is the result of this expression }

In this example, the add function returns the sum of two integers. Note that Rust functions return the value of the last expression in the function body by default, without needing a return keyword.

Early Return

You can use the return keyword to return a value early from a function.

rust
fn main() { let result = factorial(5); println!("Factorial: {}", result); } fn factorial(n: u32) -> u32 { if n == 0 { return 1; } n * factorial(n - 1) }

Function Overloading

Rust does not support function overloading (multiple functions with the same name but different parameters). You must use different names for different functions.

Functions as First-Class Citizens

In Rust, functions can be passed as arguments to other functions, returned from functions, and assigned to variables. They are first-class citizens.

Function as a Parameter

rust
fn main() { let result = operate(3, 4, add); println!("Result: {}", result); } fn add(x: i32, y: i32) -> i32 { x + y } fn operate<F>(x: i32, y: i32, func: F) -> i32 where F: Fn(i32, i32) -> i32, { func(x, y) }

In this example, operate takes a function func as a parameter and calls it.

Closures

Closures are anonymous functions that can capture their environment. They are defined using || syntax.

Basic Closure

rust
fn main() { let add = |a: i32, b: i32| -> i32 { a + b }; let result = add(5, 3); println!("The sum is: {}", result); }

Function Signatures and Type Annotations

You can specify the types of parameters and return values explicitly in function signatures. Rust's strong type system ensures type safety.

Function with Type Annotations

rust
fn multiply(x: f64, y: f64) -> f64 { x * y }

Documentation and Comments

You can document your functions using comments and documentation comments (///), which are used to generate API documentation.

Documentation Comments

rust
/// Adds two integers together. /// /// # Examples /// /// ``` /// let result = add(2, 3); /// assert_eq!(result, 5); /// ``` fn add(a: i32, b: i32) -> i32 { a + b }

Summary

  • Defining Functions: Use fn keyword followed by function name, parameters, and body.
  • Parameters: Functions can take parameters, and you specify their types.
  • Return Values: Functions can return values using -> and return the value of the last expression by default.
  • Early Return: Use return keyword for early exits.
  • Functions as First-Class Citizens: Functions can be passed as arguments and returned from other functions.
  • Closures: Anonymous functions that capture their environment.
  • Type Annotations: Specify parameter and return types explicitly.
  • Documentation: Use comments to document functions for better clarity and API documentation.

These features make Rust functions powerful and flexible, allowing for clean and efficient code.