[英]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
代碼轉換為Cell
或UnsafeCell
,因為兩者都有#[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
來消除雙重間接。
?Sized
在上面的例子中是需要的)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.