Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

9.7 Getters and Setters

Methods can provide controlled access (getters) or validated modification (setters) for fields, especially private ones.

pub struct Circle { // Assume this is in a library module
    radius: f64, // Private field
}

impl Circle {
    // Public constructor (associated function)
    pub fn new(radius: f64) -> Option<Self> {
        if radius >= 0.0 { Some(Circle { radius }) } else { None }
    }

    // Public getter
    pub fn radius(&self) -> f64 { self.radius }

    // Public setter with validation
    pub fn set_radius(&mut self, new_radius: f64) -> Result<(), &'static str> {
        if new_radius >= 0.0 {
            self.radius = new_radius; Ok(())
        } else {
            Err("Radius cannot be negative")
        }
    }

    // Calculated property (getter-like)
    pub fn diameter(&self) -> f64 { self.radius * 2.0 }
}

fn main() {
    let mut c = Circle::new(10.0).expect("Creation failed");
    println!("Radius: {}", c.radius());      // Use getter
    println!("Diameter: {}", c.diameter());

    if let Err(e) = c.set_radius(-5.0) {   // Use setter
        println!("Error setting radius: {}", e);
    }

    let _ = c.set_radius(15.0);
    println!("New radius: {}", c.radius());
}

While direct public field access is common within the same module for simple cases, getters/setters are crucial for enforcing invariants and defining stable public APIs across modules.