Search code examples
structrustmutability

How can I make only certain struct fields mutable?


I have a struct:

pub struct Test {
    pub x: i32,
    pub y: i32,
}

I'd like to have a function that mutates this — easy:

pub fn mutateit(&mut self) {
    self.x += 1;
}

This makes the entire struct mutable for the duration of the function call of mutateit, correct? I only want to mutate x, and I don't want to mutate y. Is there any way to just mutably borrow x?


Solution

  • Citing The Book:

    Rust does not support field mutability at the language level, so you cannot write something like this:

    struct Point {
        mut x: i32, // This causes an error.
        y: i32,
    }
    

    You need interior mutability, which is nicely described in the standard docs:

    use std::cell::Cell; 
    
    pub struct Test {
        pub x: Cell<i32>,
        pub y: i32
    }
    
    fn main() {
        // note lack of mut:
        let test = Test {
            x: Cell::new(1), // interior mutability using Cell
            y: 0
        };
    
        test.x.set(2);
        assert_eq!(test.x.get(), 2);
    }
    

    And, if you wanted to incorporate it in a function:

    impl Test {
        pub fn mutateit(&self) { // note: no mut again
            self.x.set(self.x.get() + 1);
        }
    }
    
    fn main() {
        let test = Test {
            x: Cell::new(1),
            y: 0
        };
    
        test.mutateit();
        assert_eq!(test.x.get(), 2);
    }