Add Behavior for packed data: rust
Binding Behavior to Structs in Rust
Rust enables you to add behavior to structs using impl
blocks. An impl block contains methods for a struct. Let’s look at an example:
struct Point {
x: i32,
y: i32,
}
impl Point {
fn x(&self) -> i32 {
self.x
}
fn y(&self) -> i32 {
self.y
}
}
fn main() {
let origin = Point { x: 0, y: 0 };
println!("The x coordinate is {}", origin.x());
println!("The y coordinate is {}", origin.y());
}
Here we have a Point
struct with x
and y
fields. We then have an impl block which contains two methods, x
and y
, which return the x
and y
coordinates respectively. We can call these methods on instances of the Point
struct, like we do in the main
function.
Methods take self
as their first parameter which is a reference to the struct the method is being called on. The &self
syntax means the method takes an immutable borrow of the struct.
Using Methods
Here’s another example of a struct with methods:
struct Rectangle {
length: u32,
width: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.length * self.width
}
}
fn main() {
let rect = Rectangle { length: 30, width: 50 };
println!(
"The area of the rectangle is {} square pixels.",
rect.area()
);
}
Here we have a Rectangle
struct with length
and width
fields. We implement a method area
which returns the area of the rectangle by multiplying the length and width. We can call rect.area()
and pass a Rectangle
instance to get its area.
Methods allow us to abstract away complex logic behind a simple interface. The area
method hides the multiplication calculation behind a simple method call.
Associated Functions
We can also have associated functions on a struct which are defined in an impl block but take the struct as an argument instead of self. This is similar to static functions in Java or C++ in some sense. Here’s an example:
struct Rectangle {
length: u32,
width: u32,
}
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle { length: size, width: size }
}
}
fn main() {
let sq = Rectangle::square(3);
println!(
"The area of the square is {}",
sq.length * sq.width
);
}
Here we have an associated function square
which takes a size and returns a Rectangle
struct where length
and width
are both equal to the passed in size. We call it with Rectangle::square(3)
and it returns a square Rectangle
struct with sides of length 3.
Associated functions are useful for constructors or factory methods. Here we use one to create a square Rectangle
.
You can have multiple impl blocks for a single struct. For example:
struct Point {
x: i32,
y: i32,
}
impl Point {
fn x(&self) -> i32 {
self.x
}
}
impl Point {
fn y(&self) -> i32 {
self.y
}
}
fn main() {
let origin = Point { x: 0, y: 0 };
println!("The x coordinate is {}", origin.x());
println!("The y coordinate is {}", origin.y());
}
Here we split the methods for Point
into two separate impl blocks. This is useful to visually separate concerns, but has no other effect - we can still call both methods on a Point
.
Here’s another example with multiple impl blocks:
struct Rectangle {
width: i32,
height: i32
}
impl Rectangle {
fn area(&self) -> i32 {
self.width * self.height
}
}
impl Rectangle {
fn perimeter(&self) -> i32 {
2 * self.width + 2 * self.height
}
}
fn main() {
let rect = Rectangle { width: 10, height: 5 };
println!("The area is: {}", rect.area());
println!("The perimeter is: {}", rect.perimeter());
}
Here we have two impl
blocks with different methods for our Rectangle
struct. One calculates the area while the other calculates the perimeter. By splitting them into two impl blocks we can visually separate these two concerns, even though both impl blocks operate on the same struct.
Conclusion
We’ve covered how to add methods and associated functions to Rust structs using impl blocks. Methods allow you to abstract logic behind an interface and associated functions act as constructors. You can also have multiple impl blocks for the same struct to visually separate concerns.
Hope this helps give you an overview of how to bind behavior to structs in Rust! Let me know if you have any other questions.