Methods and impl
#[derive(Debug)]
struct Circle {
radius: f64,
}
impl Circle {
// Associated function (constructor)
fn new(radius: f64) -> Self {
assert!(radius > 0.0, "Radius must be positive");
Circle { radius }
}
// Immutable method
fn area(&self) -> f64 { std::f64::consts::PI * self.radius * self.radius }
fn circumference(&self) -> f64 { 2.0 * std::f64::consts::PI * self.radius }
fn diameter(&self) -> f64 { self.radius * 2.0 }
// Mutable method
fn scale(&mut self, factor: f64) { self.radius *= factor; }
// Consuming method
fn into_radius(self) -> f64 { self.radius }
}
fn main() {
let mut c = Circle::new(5.0);
println!("Area: {:.2}", c.area());
println!("Circumference: {:.2}", c.circumference());
c.scale(2.0);
println!("After scale: {:?}", c);
println!("Radius: {}", c.into_radius()); // consumes c
// c is gone after into_radius
}Builder Pattern
#[derive(Debug)]
struct Server { host: String, port: u16, max_conn: usize, tls: bool }
struct ServerBuilder { host: String, port: u16, max_conn: usize, tls: bool }
impl ServerBuilder {
fn new() -> Self {
ServerBuilder { host: "localhost".to_string(), port: 8080, max_conn: 100, tls: false }
}
fn host(mut self, h: &str) -> Self { self.host = h.to_string(); self }
fn port(mut self, p: u16) -> Self { self.port = p; self }
fn max_connections(mut self, n: usize) -> Self { self.max_conn = n; self }
fn with_tls(mut self) -> Self { self.tls = true; self }
fn build(self) -> Server { Server { host: self.host, port: self.port, max_conn: self.max_conn, tls: self.tls } }
}
fn main() {
let server = ServerBuilder::new()
.host("0.0.0.0")
.port(443)
.max_connections(1000)
.with_tls()
.build();
println!("{:?}", server);
}🎯 Practice
- Implement a Stack<T> struct with push, pop (Option<T>), peek (&Option<T>), is_empty, len
- Implement a Matrix 2x2 struct with methods: new, determinant, transpose, multiply
- Use the builder pattern for a Config struct with at least 5 fields and sensible defaults
🎉 Key Takeaways
- &self: read-only access. &mut self: modification. self: consumes instance
- Associated functions (no self) are called with Type::function()
- Builder pattern: methods return Self for chaining, end with build()
- Multiple impl blocks are allowed - useful for organizing large types