2.7 Functions and Methods
Functions are defined using the fn keyword, followed by the function name, parameter list (with types), and an optional return type specified after ->.
2.7.1 Function Declaration and Return Values
// Function that takes two i32 parameters and returns an i32
fn add(a: i32, b: i32) -> i32 {
// The last expression in a block is implicitly returned
// if it doesn't end with a semicolon.
a + b
}
// Function that takes no parameters and returns nothing (unit type `()`)
fn greet() {
println!("Hello from the greet function!");
// No return value needed, implicit `()` return
}
fn main() {
let sum = add(5, 3);
println!("5 + 3 = {}", sum);
greet();
}
Key Points (Functions):
- Parameter types must be explicitly annotated.
- The return type is specified after
->. If omitted, the function returns the unit type(). - The value of the last expression in the function body is automatically returned, unless it ends with a semicolon (which turns it into a statement). The
returnkeyword can be used for early returns.
2.7.2 Methods
In Rust, methods are similar to functions but are defined within impl blocks and are associated with a specific type (like a struct or enum). The first parameter of a method is usually self, &self, or &mut self, which refers to the instance the method is called on—similar to the implicit this pointer in C++.
Methods are called using dot notation: instance.method() and can be chained.
struct Point {
x: i32,
y: i32,
}
impl Point {
// Method that calculates the distance from the origin
fn magnitude(&self) -> f64 {
// Calculate square of components, cast i32 to f64 for sqrt
((self.x.pow(2) + self.y.pow(2)) as f64).sqrt()
}
}
fn main() {
let p = Point { x: 3, y: 4 };
println!("Distance from origin: {}", p.magnitude());
}
Key Points (Methods):
- Methods are functions tied to a type and defined in
implblocks. - The first parameter is typically
self,&self, or&mut self, representing the instance. - Methods are called using dot (
.) syntax. - Methods without a
selfparameter (e.g.,String::new()) are called associated functions. These are often used as constructors or for operations related to the type but not a specific instance.
2.7.3 Comparison with C
#include <stdio.h>
// Function declaration (prototype) often needed in C
int add(int a, int b);
void greet(void);
int main() {
int sum = add(5, 3);
printf("5 + 3 = %d\n", sum);
greet();
return 0;
}
// Function definition
int add(int a, int b) {
return a + b; // Explicit return statement required
}
void greet(void) {
printf("Hello from the greet function!\n");
// No return statement needed for void functions
}
- C often requires forward declarations (prototypes) if a function is called before its definition appears. Rust generally doesn’t need them within the same module.
- C requires an explicit
returnstatement for functions returning values. Rust allows implicit returns via the last expression. - C does not have a direct equivalent to methods; behavior associated with data is typically implemented using standalone functions that take a pointer to the data structure as an argument.