我具有特征Child
和Super
,其中Super
是Child
的特征。我有一个函数,它将获取一个Rc<RefCell<dyn Child>>
实例作为参数,但是我需要将其传递给需要一个Rc<RefCell<dyn Super>>
作为参数的函数。以下代码应说明这种情况:(我正在尝试实现use_child
函数,以便它将调用use_parent
函数):
use std::{rc::Rc, cell::RefCell};
fn use_parent(parent: Rc<RefCell<dyn Super>>) {
// Use the parent functionality
}
fn use_child(child: Rc<RefCell<dyn Child>>) {
// I tried this, but it won't compile
use_parent(child as Rc<RefCell<dyn Super>>);
}
trait Super {}
trait Child: Super {}
编译器提出以下投诉:
error[E0605]: non-primitive cast: `std::rc::Rc<std::cell::RefCell<(dyn Child + 'static)>>` as `std::rc::Rc<std::cell::RefCell<dyn Super>>`
--> src/lib.rs:9:16
|
9 | use_parent(child as Rc<RefCell<dyn Super>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
我阅读了编译器的建议,但只能提出use_parent(Rc::from(child))
,它也不会编译。
从相关问题(Why doesn't Rust support trait object upcasting?)的答案来看,由于vtable问题,似乎无法(直接?)做我正在尝试的事情。该问题的另一个答案还显示了以下解决方法:
trait Base: AsBase {
// ...
}
trait AsBase {
fn as_base(&self) -> &Base;
}
impl<T: Base> AsBase for T {
fn as_base(&self) -> &Base {
self
}
}
不幸的是,我不能仅仅使用这种变通方法,因为所有内容都包裹在Rc
和RefCell
中,这使我的问题与另一个问题有所不同。
我能想到的最好的解决方法是将Rc<RefCell<dyn Child>>
和Rc<RefCell<dyn Super>>
都传递给use_child函数,其中两个Rc
都指向完全相同的单元格。这样可以解决问题,但是需要我始终保留一个额外的Rc
。此外,这感觉很脏。
那么有人知道更好的解决方案吗?