rust 在函数返回中,结构不会强制为已实现的动态特性类型

vxf3dgd4  于 2023-01-30  发布在  其他
关注(0)|答案(1)|浏览(165)

我有下面的 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中吗?有没有一种变通方法或某种方法可以使它在不改变结构Adata字段类型的情况下起作用?

tjrkku2a

tjrkku2a1#

Rc<dyn TraitB>的大小是Rc<B>的两倍(两个usize对一个usize)。因此,* 不可能 * 有一种方法在不重新构建向量的情况下将Vec<Rc<B>>强制为Vec<Rc<dyn TraitB>>
您可以存储Vec<Rc<dyn TraitB>>,但只能使用推送B的方法,从而防止误用。

相关问题