Rust Functions
Organizing and reusing code in Rust
๐ง What are Functions in Rust?
Functions in Rust are reusable blocks of code that perform specific tasks. They help organize code, avoid repetition, and make programs easier to understand and maintain.
// Basic function definition
fn greet() {
println!("Hello, World!");
}
// Function with parameters and return value
fn add(a: i32, b: i32) -> i32 {
a + b // implicit return
}
fn main() {
greet();
let result = add(5, 3);
println!("5 + 3 = {}", result);
}
Output:
5 + 3 = 8
Function Components
Definition
Use fn keyword to define functions
fn function_name() {
// code here
}
Parameters
Accept input values
fn greet(name: &str) {
println!("Hello, {}!", name);
}
Return Values
Send values back to caller
fn square(x: i32) -> i32 {
x * x
}
Calling
Execute functions by name
let result = square(5);
greet("Alice");
๐น Basic Function Syntax
Functions are defined with the fn keyword:
// Function without parameters
fn say_hello() {
println!("Hello there!");
}
// Function with parameters
fn introduce(name: &str, age: u32) {
println!("Hi, I'm {} and I'm {} years old", name, age);
}
fn main() {
say_hello();
introduce("Alice", 25);
introduce("Bob", 30);
}
Output:
Hi, I'm Alice and I'm 25 years old
Hi, I'm Bob and I'm 30 years old
๐น Functions with Return Values
Functions can return values using the -> syntax:
// Function that returns a value
fn multiply(x: i32, y: i32) -> i32 {
x * y // No semicolon = implicit return
}
// Function with explicit return
fn divide(x: f64, y: f64) -> f64 {
if y != 0.0 {
return x / y; // explicit return with semicolon
}
0.0 // implicit return
}
fn main() {
let product = multiply(4, 7);
let quotient = divide(10.0, 3.0);
println!("4 ร 7 = {}", product);
println!("10 รท 3 = {:.2}", quotient);
}
Output:
10 รท 3 = 3.33
๐น Functions with Multiple Parameters
Functions can accept multiple parameters of different types:
fn calculate_area(length: f64, width: f64) -> f64 {
length * width
}
fn format_person(name: &str, age: u32, city: &str) -> String {
format!("{} is {} years old and lives in {}", name, age, city)
}
fn main() {
let area = calculate_area(5.5, 3.2);
println!("Rectangle area: {:.1} square units", area);
let person_info = format_person("Emma", 28, "New York");
println!("{}", person_info);
}
Output:
Emma is 28 years old and lives in New York
๐น Function Expressions and Statements
Understanding the difference between expressions and statements:
fn examples() -> i32 {
let x = 5; // statement
let y = {
let inner = 3;
inner + 1 // expression (no semicolon)
}; // y = 4
x + y // expression - returns 9
}
fn conditional_return(number: i32) -> &'static str {
if number > 0 {
"positive" // expression
} else if number < 0 {
"negative" // expression
} else {
"zero" // expression
}
}
fn main() {
println!("Result: {}", examples());
println!("5 is {}", conditional_return(5));
println!("-3 is {}", conditional_return(-3));
println!("0 is {}", conditional_return(0));
}
Output:
5 is positive
-3 is negative
0 is zero
๐น Function Best Practices
โ Good Practices:
- Descriptive names: Use clear, descriptive function names
- Single responsibility: Each function should do one thing well
- Type annotations: Always specify parameter and return types
- Small functions: Keep functions short and focused
๐ Naming Convention:
-
Use
snake_casefor function names - Use verbs for functions that perform actions
- Use descriptive names that explain what the function does
// Good function names
fn calculate_tax(income: f64, rate: f64) -> f64 {
income * rate
}
fn is_even(number: i32) -> bool {
number % 2 == 0
}
fn convert_to_uppercase(text: &str) -> String {
text.to_uppercase()
}