簡體   English   中英

如何移動 Vec <box<dyn trait> &gt; 走進 Vec <rc<refcell<dyn trait> &gt;&gt; </rc<refcell<dyn></box<dyn>

[英]How to move a Vec<Box<dyn Trait>> Into Vec<Rc<RefCell<dyn Trait>>>

我有一個Vec<Box<dyn Trait>>作為輸入,我想將它的元素存儲在Vec<Rc<RefCell<dyn Trait>>>中。 最好的方法是什么?

我試過:

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);
    }
}

但我得到了錯誤:

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`

是否真的有可能或者我需要更改輸入類型?

雖然RefCell<dyn Trait>是一個有效類型,但由於RefCell<T>的聲明允許T: ?Sized ,目前似乎沒有一種方法可以從模塊外部創建一個,除了CoerceUnsized ,它需要從一個大小的值。

但是,您應該能夠使用unsafe代碼轉換為CellUnsafeCell ,因為兩者都有#[repr(transparent)]

如果您控制Trait ,一種選擇是通過推遲到內部實現來簡單地為Box<dyn Trait>實現它:

// 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的 object 包裝在第二個指針( Rc )后面,因此如果您在性能敏感算法中使用dest ,則必須取消引用它兩次而不是一次。 如果您能夠重組代碼以便接受Box<T: Trait> ,則可以通過將T移出Box並進入RefCell來消除雙重間接。

相關問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM