我有下面的 rust 代码
use std::{
cell::{Ref, RefCell},
rc::Rc,
};
trait TraitA {
fn data(&self) -> Ref<Vec<Rc<dyn TraitB>>>;
}
struct A {
data: RefCell<Vec<Rc<B>>>,
}
impl TraitA for A {
fn data(&self) -> Ref<Vec<Rc<dyn TraitB>>> {
self.data.borrow()
}
}
trait TraitB {}
struct B {}
impl TraitB for B {}
但是,我得到以下错误
error[E0308]: mismatched types
--> src/lib.rs:16:9
|
15 | fn data(&self) -> Ref<Vec<Rc<dyn TraitB>>> {
| ------------------------ expected `Ref<'_, Vec<Rc<(dyn TraitB + 'static)>>>` because of return type
16 | self.data.borrow()
| ^^^^^^^^^^^^^^^^^^ expected trait object `dyn TraitB`, found struct `B`
|
= note: expected struct `Ref<'_, Vec<Rc<(dyn TraitB + 'static)>>>`
found struct `Ref<'_, Vec<Rc<B>>>`
我试过将A
中的data
字段设置为RefCell<Vec<Rc<dyn TraitB>>>
类型,这将起作用。
然而,在我的实现中,我希望字段包含B
类型,因为我希望Vec * 仅 * 存储B
类型,而不是TraitB
的任何实现。
我的理解是Rust应该能够强制B
类型,只要它实现了trait TraitB
,在上面的例子中,B
确实实现了TraitB
。
例如,在下面的代码段中,Rc<dyn TraitB>
被成功强制为Rc<B>
,没有问题。
struct C {
weak_ref: Weak<B>,
}
impl C {
fn upgrade_weak_ref(&self) -> Rc<dyn TraitB> {
self.weak_ref.upgrade().unwrap()
}
}
所以我的问题是,为什么强制在上面的第一个例子中不起作用?是因为它包含在Ref
中吗?有没有一种变通方法或某种方法可以使它在不改变结构A
中data
字段类型的情况下起作用?
1条答案
按热度按时间tjrkku2a1#
Rc<dyn TraitB>
的大小是Rc<B>
的两倍(两个usize对一个usize)。因此,* 不可能 * 有一种方法在不重新构建向量的情况下将Vec<Rc<B>>
强制为Vec<Rc<dyn TraitB>>
。您可以存储
Vec<Rc<dyn TraitB>>
,但只能使用推送B
的方法,从而防止误用。