我试图为Box::new
提供静态方法引用和类型参数,并且无法管理它。
我有以下结构:
trait MyTrait {
fn hello(&self);
}
struct MyStruct;
impl MyTrait for MyStruct {
fn hello(&self) {
println!("Hello");
}
}
在我的main方法中,我想将这些结构转换为trait对象,将它们放在Box
中,并将其作为向量返回。我设法这样做:
fn main() {
let my_vec = vec![MyStruct];
let my_trait_vec: Vec<Box<MyTrait>> = my_vec
.into_iter()
.map(|x| {
let boxed: Box<MyTrait> = Box::new(x);
boxed
})
.collect();
}
我正在寻找类似的东西:
let mut my_trait_vec: Vec<Box<MyTrait>> = my_vec.into_iter().map(Box::new::<MyTrait>).collect();
这不被编译器接受,它抱怨Box::new()
的意外类型参数。
是否可以在单行中进行此装箱操作而不声明任何外部功能?
由于您要为Box
类型提供类型参数,因此正确的语法将是Box::<dyn MyTrait>::new
而不是Box::new::<dyn MyTrait>
。但是,这也不起作用,因为编译器会尝试将Box::new()
的参数类型强制转换为dyn MyTrait
,然后再按值传递,这对于动态大小的类型是不可能的。您需要先创建该框,然后才能执行未分级的强制,因此您拥有的代码很好。这是一个基本相同的替代方案,只是写得更简洁:
let mut my_trait_vec: Vec<Box<dyn MyTrait>> = my_vec
.into_iter()
.map(|x| Box::new(x) as Box<dyn MyTrait>)
.collect();
另一种选择是定义辅助函数,例如,
fn into_boxed_trait<T>(value: T) -> Box<dyn MyTrait>
where
T: MyTrait + 'static,
{
Box::new(value)
}
这将允许你写
let mut my_trait_vec: Vec<_> = my_vec
.into_iter()
.map(into_boxed_trait)
.collect();