I have a struct (Foo) that has an Rc<RefCell<Bar>>
field, Bar has a method that gets called by a Rc<RefCell<Bar>>
, in that method it gets a reference to a Foo and I would like to set that Rc<RefCell<Bar>>
in in that Foo to the Bar that called the method.
Consider the following code:
struct Foo {
thing: Rc<RefCell<Bar>>,
}
struct Bar;
impl Foo {
pub fn set_thing(&mut self, thing: Rc<RefCell<Bar>>) {
self.thing = thing;
}
}
impl Bar {
pub fn something(&mut self) {
// Things happen, I get a &mut to a Foo, and here I would like to use this Bar reference
// as the argument needed in Foo::set_thing
}
}
// Somewhere else
// Bar::something is called from something like this:
let my_bar : Rc<RefCell<Bar>> = Rc::new(RefCell::new(Bar{}));
my_bar.borrow_mut().something();
// ^--- I'd like my_bar.clone() to be "thing" in the foo I get at Bar::something
Is the only way to do what I want to add another parameter to Bar::something
accepting an Rc<RefCell<Bar>>
? It feels redudant, when I'm already calling it from one.
pub fn something(&mut self, rcSelf: Rc<RefCell<Bar>>) {
foo.set_thing(rcSelf);
The RefCell<T> keeps track of how many Ref<T> and RefMut<T> smart pointers are currently active. Every time we call borrow , the RefCell<T> increases its count of how many immutable borrows are active. When a Ref<T> value goes out of scope, the count of immutable borrows goes down by one.
In fact, RefCell<T> is Send , at least when T: Send . You have a RefCell<&'a mut [T]> , which means that to make the RefCell Send all you need is to add a T: Send bound...
A RefCell is another way to change values without needing to declare mut . It means "reference cell", and is like a Cell but uses references instead of copies.
There are two main choices here:
Use a static method:
impl Bar {
pub fn something(self_: Rc<RefCell<Bar>>) {
…
}
}
Bar::something(my_bar)
Conceal the fact that you’re using Rc<RefCell<X>>
, wrapping it in a new type with the single field Rc<RefCell<X>>
; then other types can use this new type rather than Rc<RefCell<Bar>>
and you can make this something
method work with self
. This may or may not be a good idea, depending on how you use it. Without further details it’s hard to say.
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