Andrew
Andrew

Reputation: 167

How to make &mut self from &self?

I want to expose a public function with immutable self which calls a private function with mutable self.

struct Foo {
    value: i32,
}

impl Foo {
    fn f1(&self) {
        self.f2(); // <--- is it possible to make self mutable?
    }

    fn f2(&mut self) {
        self.value = 5;
    }
}

fn main() {
    let foo = Foo { value: 0 };
    foo.f1();
}

When compiling this code I get an error

cannot borrow immutable borrowed content *self as mutable

Is it possible to make self mutable?

Upvotes: 2

Views: 2355

Answers (2)

rodrigo
rodrigo

Reputation: 98378

What you want cannot be done: you cannot convert a non-mutable reference into a mutable one.

But you can get almost that with RefCell:

struct Foo { value: RefCell<i32> }

impl Foo {
    fn f1(&self) {
        let mutValue = self.value.borrow_mut();
        *mutValue = 5;
    }
}

I didn't even need the f2 function!

Upvotes: 5

Simon Whitehead
Simon Whitehead

Reputation: 65079

EDIT:

After missing that last sentence.. you could get away with wrapping the property in a Cell:

use std::cell::Cell;

struct Foo { value: Cell<i32> }

impl Foo {
  fn f1(&self) {
    self.f2();
  }

  fn f2(&self) {
    self.value.set(5);
  }
}

fn main() {
    let foo = Foo { value: Cell::new(0) };
    foo.f1();
    println!("{:?}", foo.value.get()); // prints 5
}

Upvotes: 6

Related Questions