I have originally asked this question here, but it was marked as duplicate, although it duplicates only a part of it in my opinion, so I have created a more specific one:
Consider the following code:
use std::rc::Rc; trait MyTrait { fn trait_func(&self); } struct MyStruct1; impl MyStruct1 { fn my_fn(&self) { // do something } } impl MyTrait for MyStruct1 { fn trait_func(&self) { // do something } } fn my_trait_fn(t: Rc<MyTrait>) { t.trait_func(); } fn main() { let my_str: Rc<MyStruct1> = Rc::new(MyStruct1); my_trait_fn(my_str.clone()); my_str.my_fn(); }
This code works fine. Now I want to change the definition of trait_func
to accept a &mut self
, but it won't work as Rc
works with immutable data only. The solution I use is to wrap MyTrait
into RefCell
:
use std::cell::RefCell; fn my_trait_fn(t: Rc<RefCell<Box<MyTrait>>>) { t.borrow_mut().trait_func(); } fn main() { let my_str: Rc<RefCell<Box<MyStruct1>>> = Rc::new(RefCell::new(Box::new(MyStruct1))); my_trait_fn(my_str.clone()); my_str.my_fn(); }
When I compile it I get an error:
error[E0308]: mismatched types --> src/main.rs:27:17 | 27 | my_trait_fn(my_str.clone()); | ^^^^^^^^^^^^^^ expected trait MyTrait, found struct `MyStruct1` | = note: expected type `std::rc::Rc<std::cell::RefCell<std::boxed::Box<MyTrait + 'static>>>` found type `std::rc::Rc<std::cell::RefCell<std::boxed::Box<MyStruct1>>>` = help: here are some functions which might fulfill your needs: - .into_inner()
What's the best way to go around this problem?