我最初问过这个问题here,但它被标记为重复,虽然它只复制了其中的一部分,所以我创建了一个更具体的问题:
考虑以下代码:
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()解决这个问题最好的方法是什么?
发布于 2015-06-16 07:55:55
(这个答案的旧版本基本上建议克隆底层结构,并将其放入一个新的Rc<RefCell<Box<MyTrait>>对象中;这在稳定锈蚀的时候是必要的,但不久之后,Rc<RefCell<MyStruct>>将毫不费力地胁迫Rc<RefCell<MyTrait>>。)
放下Box<>包装,您可以自由和轻松地胁迫Rc<RefCell<MyStruct>>到Rc<RefCell<MyTrait>>。回顾一下,克隆Rc<T>只会产生另一个Rc<T>,从而使回溯数增加一个,您可以这样做:
use std::rc::Rc;
use std::cell::RefCell;
trait MyTrait {
fn trait_func(&self);
}
#[derive(Clone)]
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<RefCell<MyTrait>>) {
t.borrow_mut().trait_func();
}
fn main() {
// (The type annotation is not necessary here, but helps explain it.
// If the `my_str.borrow().my_fn()` line was missing, it would actually
// be of type Rc<RefCell<MyTrait>> instead of Rc<RefCell<MyStruct1>>,
// essentially doing the coercion one step earlier.)
let my_str: Rc<RefCell<MyStruct1>> = Rc::new(RefCell::new(MyStruct1));
my_trait_fn(my_str.clone());
my_str.borrow().my_fn();
}作为一般规则,看看是否可以通过引用(理想情况下甚至是泛型的--fn my_trait_fn<T: MyTrait>(t: &T)和类似的方法)使事物接受包含的值,这通常可以被称为my_str.borrow(),并通过自动引用和取消引用来处理其余部分,而不是整个Rc<RefCell<MyTrait>>。
https://stackoverflow.com/questions/30861295
复制相似问题