impl Blocks
impl block is where you teach a struct how to do things, by writing functions that belong to it.In this page:
impl Name {
fn method(&self) -> ReturnType {
// body
}
}
Defining an impl Block
An impl block associates functions with a specific struct, letting you group behavior together with the data it operates on rather than scattering unrelated free functions.
Example: Defining an impl Block
// Define a struct `Rectangle` to group related fields together
struct Rectangle {
width: f64,
height: f64,
}
// Implement methods on `Rectangle`
impl Rectangle {
// Define the function `area` taking `&self` and returning a floating-point number
fn area(&self) -> f64 {
self.width * self.height
}
}
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `rect`, set to `Rectangle { width: 4.0, height: 3.0 }`
let rect = Rectangle { width: 4.0, height: 3.0 };
// Print "Area: {}" to the console, substituting in `rect.area()` (with a trailing newline)
println!("Area: {}", rect.area());
}
Login to try C/C++/Java/PHP code in the editor
Multiple Methods in One impl Block
A single impl block can define as many methods as needed, each becoming callable on any instance of that struct using dot notation.
Example: Multiple Methods in One impl Block
// Define a struct `Rectangle` to group related fields together
struct Rectangle {
width: f64,
height: f64,
}
// Implement methods on `Rectangle`
impl Rectangle {
// Define the function `area` taking `&self` and returning a floating-point number
fn area(&self) -> f64 {
self.width * self.height
}
// Define the function `perimeter` taking `&self` and returning a floating-point number
fn perimeter(&self) -> f64 {
2.0 * (self.width + self.height)
}
}
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `rect`, set to `Rectangle { width: 5.0, height: 2.0 }`
let rect = Rectangle { width: 5.0, height: 2.0 };
// Print "Area: {}, Perimeter: {}" to the console, substituting in `rect.area(), rect.perimeter()` (with a trailing newline)
println!("Area: {}, Perimeter: {}", rect.area(), rect.perimeter());
}
Login to try C/C++/Java/PHP code in the editor
Multiple impl Blocks for the Same Struct
Rust allows splitting a struct's behavior across several impl blocks; they are merged together by the compiler, which can be useful for organizing large amounts of functionality.
Example: Multiple impl Blocks for the Same Struct
// Define a struct `Circle` to group related fields together
struct Circle {
radius: f64,
}
// Implement methods on `Circle`
impl Circle {
// Define the function `area` taking `&self` and returning a floating-point number
fn area(&self) -> f64 {
3.14159 * self.radius * self.radius
}
}
// Implement methods on `Circle`
impl Circle {
// Define the function `diameter` taking `&self` and returning a floating-point number
fn diameter(&self) -> f64 {
self.radius * 2.0
}
}
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `c`, set to `Circle { radius: 3.0 }`
let c = Circle { radius: 3.0 };
// Print "Area: {:.2}, Diameter: {}" to the console, substituting in `c.area(), c.diameter()` (with a trailing newline)
println!("Area: {:.2}, Diameter: {}", c.area(), c.diameter());
}
Login to try C/C++/Java/PHP code in the editor
Methods Can Take Extra Parameters
Beyond self, methods can accept additional parameters just like regular functions, allowing them to compute results based on outside input as well as the struct's own data.
Example: Methods Can Take Extra Parameters
// Define a struct `Rectangle` to group related fields together
struct Rectangle {
width: f64,
height: f64,
}
// Implement methods on `Rectangle`
impl Rectangle {
// Define the function `scaled_area` taking `&self`, `factor` and returning a floating-point number
fn scaled_area(&self, factor: f64) -> f64 {
self.width * self.height * factor
}
}
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `rect`, set to `Rectangle { width: 2.0, height: 3.0 }`
let rect = Rectangle { width: 2.0, height: 3.0 };
// Print "Scaled area: {}" to the console, substituting in `rect.scaled_area(2.0)` (with a trailing newline)
println!("Scaled area: {}", rect.scaled_area(2.0));
}
Login to try C/C++/Java/PHP code in the editor
- Writing free-standing functions that take a struct as their first argument instead of grouping them into an
implblock. - Forgetting that a struct can have multiple
implblocks -- Rust allows splitting them for organization. - Confusing methods (which take
self) with associated functions (which don't) when writing them inside the sameimplblock.
impl TypeName { ... }associates functions with a particular struct type.- Functions inside an
implblock that takeselfas their first parameter are called methods. - A struct can have more than one
implblock; Rust merges them together. - Grouping behavior in
implblocks keeps related logic organized next to the data it operates on.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: