如何使用类型参数将变量框作为静态方法引用?

问题描述 投票:3回答:1

我试图为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()的意外类型参数。

是否可以在单行中进行此装箱操作而不声明任何外部功能?

Playground

rust
1个回答
4
投票

由于您要为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();
© www.soinside.com 2019 - 2024. All rights reserved.