![](/img/trans.png)
[英]Downcasting a Rc<RefCell<Box<struct>>> to Rc<RefCell<Box<dyn trait>>>
[英]How do I pass Rc<RefCell<Box<MyStruct>>> to a function accepting Rc<RefCell<Box<dyn MyTrait>>>?
我最初在这里问了这个问题,但它被标记为重复,虽然它在我看来只复制了它的一部分,所以我创建了一个更具体的一个:
请考虑以下代码:
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<RefCell<Box<MyTrait>>
对象;这在稳定Rust的时候是必要的,但是在那之后不久, Rc<RefCell<MyStruct>>
将Rc<RefCell<MyStruct>>
强制转到Rc<RefCell<MyTrait>>
。)
放下Box<>
包装,你可以轻松地将Rc<RefCell<MyTrait>>
强制Rc<RefCell<MyStruct>>
为Rc<RefCell<MyTrait>>
。 回想克隆一个Rc<T>
只产生另一个Rc<T>
,将refcount增加一,你可以这样做:
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>>
事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.