首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将Vec<Box<dyn Trait>>移动到Vec<Rc<RefCell<dyn Trait>>>中

如何将Vec<Box<dyn Trait>>移动到Vec<Rc<RefCell<dyn Trait>>>中
EN

Stack Overflow用户
提问于 2020-05-24 01:47:44
回答 2查看 470关注 0票数 5

我有一个Vec<Box<dyn Trait>>作为输入,我想在Vec<Rc<RefCell<dyn Trait>>>中存储它的元素。做这件事最好的方法是什么?

我尝试过:

代码语言:javascript
复制
use std::cell::RefCell;
use std::rc::Rc;

trait Trait {}

fn main() {
    let mut source: Vec<Box<dyn Trait>> = Vec::new();
    let mut dest: Vec<Rc<RefCell<dyn Trait>>> = Vec::new();

    for s in source {
        let d = Rc::new(RefCell::new(s.as_ref()));
        dest.push(d);
    }
}

但是我得到了一个错误:

代码语言:javascript
复制
error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied
  --> src/main.rs:12:19
   |
12 |         dest.push(d);
   |                   ^ the trait `Trait` is not implemented for `&dyn Trait`
   |
   = note: required for the cast to the object type `dyn Trait`

这实际上是可能的,还是我需要更改输入类型?

EN

回答 2

Stack Overflow用户

发布于 2020-05-24 05:37:43

虽然RefCell<dyn Trait>是一个有效的类型,但由于RefCell的声明允许T: ?Sized,因此除了CoerceUnsized之外,目前似乎没有其他方法可以从模块外部创建一个,它需要以大小的值开始。

但是,您应该能够使用unsafe代码转换为CellUnsafeCell,因为两者都有#[repr(transparent)]

票数 1
EN

Stack Overflow用户

发布于 2020-05-24 07:04:02

如果您控制Trait,一种选择是通过推迟到内部实现来简单地为Box<dyn Trait>实现它:

代码语言:javascript
复制
// We could implement Trait only for Box<dyn Trait>, but usually what you want
// is to implement it for all Boxes of things that are Trait instead
impl<T: ?Sized + Trait> Trait for Box<T> {}

fn pushes(dest: &mut Vec<Rc<RefCell<dyn Trait>>>, source: Vec<Box<dyn Trait>>) {
    for s in source {
        dest.push(Rc::new(RefCell::new(s)));
    }
}

请注意,这会将已经Box的ed对象包装在第二个指针(Rc)之后,因此如果您在对性能敏感的算法中使用dest,它将不得不两次而不是一次取消对它的引用。如果能够重构代码以接受Box<T: Trait>,则可以通过将T移出Box并将其移入RefCell来消除双重间接性。

相关问题

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61976226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档