我正在尝试将 Rc<RefCell<Data>>
转换为 Rc<RefCell<dyn Interface>>
(Data
实现了 Interface
),但无法在通用方法中实现:
use std::cell::RefCell;
use std::rc::Rc;
trait Interface {
fn pouet(&self);
}
struct Data {}
impl Interface for Data {
fn pouet(&self) {
println!("pouet");
}
}
fn helper<T>(o: &Rc<RefCell<T>>)
where
T: Interface,
{
let t = o as &Rc<RefCell<dyn Interface>>;
work(t);
}
fn work(o: &Rc<RefCell<dyn Interface>>) {
o.borrow().pouet();
}
fn main() {
// work
{
let o = Rc::new(RefCell::new(Data {}));
work(&(o as Rc<RefCell<dyn Interface>>));
}
// raise an compile error
{
let o = Rc::new(RefCell::new(Data {}));
helper(&o);
}
}
我在非原始类型转换上遇到了编译错误:
error[E0605]: non-primitive cast: `&Rc<RefCell<T>>` as `&Rc<RefCell<dyn Interface>>`
--> src/main.rs:20:13
|
20 | let t = o as &Rc<RefCell<dyn Interface>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
struct Foo { field: u8 }
的大小为1个字节。然而,为了将我们的对象用作特质对象(将其视为实现特质的某个随机对象),我们现在必须将其存储在一个描述如何使用它的函数表中,称为vtable。vtable只是一个指向我们特质实现的表。 - Coder-256run()
的特质MyTrait
,我们有实现MyTrait
的结构体Foo
和Bar
,然后我们有一个包含许多Foo
和Bar
的Vec<Box<dyn MyTrait>>
。每个特质对象(dyn MyTrait
)必须包含指向其版本的run()
的指针,以便我们知道如何调用它。所以回到问题,问题是您需要存储指向特质中所有方法的指针表,以便能够使用它。 - Coder-256o
只是指向Data
实例的指针,而你想让它成为dyn Interface
实例。dyn Interface
由vtable和“实际”类型组成(因此在此情况下,它由vtable加上Data
实例组成)。一种看法是:你有一个指向Data
的指针,并试图将其强制转换为指向dyn Interface
的指针(即vtable加上Data
),所以当然会失败,因为它们不相同。 - Coder-256