Methods in Rust
Rust supports methods defined on struct types.
struct Rect {
width: i32,
height: i32,
}
// This `area` method is associated with the `Rect` struct.
impl Rect {
fn area(&self) -> i32 {
self.width * self.height
}
// Methods can be defined for either borrowed or owned self.
// Here's an example of a method that takes ownership of self.
fn perim(self) -> i32 {
2 * self.width + 2 * self.height
}
}
fn main() {
let r = Rect { width: 10, height: 5 };
// Here we call the 2 methods defined for our struct.
println!("area: {}", r.area());
println!("perim: {}", r.perim());
// In Rust, method calls automatically dereference when calling a method on a reference.
// You don't need to explicitly dereference.
let rp = &r;
println!("area: {}", rp.area());
// Note: We can't call perim() on rp because it takes ownership,
// and we can't move out of a borrowed context.
// This line would cause a compilation error:
// println!("perim: {}", rp.perim());
}
To run the program:
$ rustc methods.rs
$ ./methods
area: 50
perim: 30
area: 50
In Rust, methods are defined within impl
blocks. The &self
in the area
method is similar to this
in other languages, but in Rust, you explicitly specify whether you’re borrowing (&self
), mutably borrowing (&mut self
), or taking ownership (self
).
Rust doesn’t require explicit dereferencing when calling methods on references. This is known as “auto-dereferencing” or “deref coercion”.
Note that in this Rust version, we can’t call perim()
on a reference because it takes ownership of self
. This demonstrates Rust’s ownership system, which prevents use-after-move errors at compile time.
Next, we’ll look at Rust’s mechanism for defining abstract behavior: traits.