我最初在这里提出了这个问题,但它被标记为重复,尽管在我看来只有一部分是重复的,因此我创建了一个更具体的问题:
考虑以下代码:
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<dyn MyTrait>) {
t.trait_func();
}
fn main() {
let my_str: Rc<MyStruct1> = Rc::new(MyStruct1);
my_trait_fn(my_str.clone());
my_str.my_fn();
}
这段代码运行良好。现在我想将trait_func
的定义更改为接受&mut self
,但由于Rc
仅适用于不可变数据,所以这样做不起作用。 我使用的解决方案是将MyTrait
包装到RefCell
中:
use std::cell::RefCell;
fn my_trait_fn(t: Rc<RefCell<Box<dyn 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();
}
当我编译它时,出现了错误:
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<dyn 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()
什么是解决此问题的最佳方法?
Rc<MyTrait>
。第二段代码使用了额外的Box
,这只在稳定版本中才是必需的。如果没有Box
,你的代码在夜版中可以正常工作,只需要进行一些小的修改。请编辑你的问题,如果你想要一个稳定版本的解决方案。 - oli_obkBox
似乎是解决我的问题的方法。我认为RefCell
直接与 Trait 一起工作的能力是最近引入的,这就是为什么最初对我不起作用的原因(当我大约两周前更新我的 Rust 夜版时)。 - Dmitry Uvarov