如何将Rc <RefCell <dyn Child >>用作Rc <RefCell <dyn Super >>?

时间:2019-10-27 21:01:38

标签: rust

我具有特征ChildSuper,其中SuperChild的特征。我有一个函数,它将获取一个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
    }
}

不幸的是,我不能仅仅使用这种变通方法,因为所有内容都包裹在RcRefCell中,这使我的问题与另一个问题有所不同。

我能想到的最好的解决方法是将Rc<RefCell<dyn Child>>Rc<RefCell<dyn Super>>都传递给use_child函数,其中两个Rc都指向完全相同的单元格。这样可以解决问题,但是需要我始终保留一个额外的Rc。此外,这感觉很脏。

那么有人知道更好的解决方案吗?

0 个答案:

没有答案