Module 3 • Lesson 16

Methods on Structs

📚 8 min read 💻 Free Course 🦀 nixus.pro

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

  1. Implement a Stack<T> struct with push, pop (Option<T>), peek (&Option<T>), is_empty, len
  2. Implement a Matrix 2x2 struct with methods: new, determinant, transpose, multiply
  3. Use the builder pattern for a Config struct with at least 5 fields and sensible defaults

🎉 Key Takeaways