In the following code, I am trying to change the value of a refcounted object by calling one of its methods:
use std::rc::Rc;
fn main() {
let mut x = Rc::new(Thing { num: 50 });
x.what_to_do_to_get_mut_thing().change_num(19); //what do i do here
}
pub struct Thing {
pub num: u32,
}
impl Thing {
pub fn change_num(&mut self, newnum: u32) {
self.num = newnum;
}
}
I am using the get_mut
function to achieve this, but I don't know if this is a standard way to accomplish this.
if let Some(val) = Rc::get_mut(&mut x) {
val.change_num(19);
}
The documentation for Rc
says:
See the module-level documentation for more details.
Which has this text:
This is difficult because
Rc
enforces memory safety by only giving out shared references to the value it wraps, and these don't allow direct mutation. We need to wrap the part of the value we wish to mutate in aRefCell
, which provides interior mutability: a method to achieve mutability through a shared reference.RefCell
enforces Rust's borrowing rules at runtime.
It then demonstrates how to use it.
If you didn't read the API documentation, you might have instead chosen to read the entire chapter about Rc
in The Rust Programming Language. It has this to say:
Via immutable references,
Rc<T>
allows you to share data between multiple parts of your program for reading only. IfRc<T>
allowed you to have multiple mutable references too, you might violate one of the borrowing rules discussed in Chapter 4: multiple mutable borrows to the same place can cause data races and inconsistencies. But being able to mutate data is very useful! In the next section, we’ll discuss the interior mutability pattern and theRefCell<T>
type that you can use in conjunction with anRc<T>
to work with this immutability restriction.
Applying this new knowledge to your code:
use std::{cell::RefCell, rc::Rc};
fn main() {
let x = Rc::new(RefCell::new(Thing { num: 50 }));
x.borrow_mut().change_num(19);
}
See also:
I am using the
get_mut
function
It's very unlikely that you want to use this.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With