如何对实现特征的类型的迭代器的内容进行装箱?

Alp*_*der 5 boxing iterator rust

我正在采用某种类型的迭代器,该迭代器必须实现 Trait A,并尝试将其转换为该 Trait 的 a Vecof Boxes :

trait A {}

fn test2<'a, I>(iterator: I) -> Vec<Box<A + 'a>>
where
    I: IntoIterator,
    I::Item: A + 'a,
{
    iterator
        .into_iter()
        .map(|a| Box::new(a))
        .collect::<Vec<Box<A + 'a>>>()
}
Run Code Online (Sandbox Code Playgroud)

然而,这无法编译,并说:

trait A {}

fn test2<'a, I>(iterator: I) -> Vec<Box<A + 'a>>
where
    I: IntoIterator,
    I::Item: A + 'a,
{
    iterator
        .into_iter()
        .map(|a| Box::new(a))
        .collect::<Vec<Box<A + 'a>>>()
}
Run Code Online (Sandbox Code Playgroud)

这个错误有点道理,但我不明白为什么以下内容没有问题:

fn test<'a, T: A + 'a>(t: T) -> Box<A + 'a> {
    Box::new(t)
}
Run Code Online (Sandbox Code Playgroud)

这有什么不同吗?我如何表达我希望Box它们是As,而不是它们可能是什么类型?

She*_*ter 3

您需要将 转换Box<I::Item>Box<A>

fn test2<'a, I>(iterator: I) -> Vec<Box<dyn A + 'a>>
where
    I: IntoIterator,
    I::Item: A + 'a,
{
    iterator
        .into_iter()
        .map(|a| Box::new(a) as Box<dyn A>)
        .collect()
}
Run Code Online (Sandbox Code Playgroud)

[Box::new直接返回]有何不同?

正如斯文·马尔纳克指出的

不需要在函数中显式转换的原因是块的最后一个语句是强制转换站点,并且强制转换在这些站点隐式发生。有关更多详细信息,请参阅注释中有关强制的章节。