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
return
keyword 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
impl
blocks. - The first parameter is typically
self
,&self
, or&mut self
, representing the instance. - Methods are called using dot (
.
) syntax. - Methods without a
self
parameter (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
return
statement 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.