如何将非对象安全的 Trait 包装在对象安全的 Trait 中?

Qqw*_*qwy 5 iterator traits dynamic-dispatch rust

我最初在尝试创建一个 Rayon ParallelIterator 时遇到了这个问题,该flat_map操作被应用于动态次数,请参阅 Rayon 问题跟踪器上的这篇文章

注意:我也在 Rust 用户论坛上问过同样的问题(请参阅此处),但 StackOverflow 可能是解决此问题的更好场所。

对于标准(即串行执行)Iterators 以下工作:

fn fancy<Input, Output, Item>(input: Input, depth: usize) -> Output
where
    Input : IntoIterator<Item = Item>,
    Output : std::iter::FromIterator<Item>,
    Item : Copy + std::ops::Add<Output = Item>,
{
    let mut iter: Box<dyn Iterator<Item = Item>> = Box::new(input.into_iter());
    for _ in 0..depth {
        iter = Box::new(iter.flat_map(|x| vec![x, x + x].into_iter()));
    }
    iter.collect()
}
Run Code Online (Sandbox Code Playgroud)

ParallelIterator然而,当使用 Rayon 的s 时,事情变得不确定:ParallelIterator需要实现它的类型是Sized,使它们非对象安全,因此不可能作为特征对象传递。因此,以下直接翻译不起作用:

use rayon::prelude::*;
fn fancy2<Input, Output, Item>(input: Input, depth: usize) -> Output
where
    Input : IntoParallelIterator<Item = Item>,
    Output : FromParallelIterator<Item>,
    Item : Copy + std::ops::Add<Output = Item> + Send,
{
    let mut iter: Box<dyn rayon::iter::ParallelIterator<Item = Item>> = Box::new(input.into_par_iter());
    for _ in 0..depth {
        iter = Box::new(iter.flat_map(|x| vec![x, x + x].into_par_iter()));
    }
    iter.collect()
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:我们如何像ParallelIterator在对象安全的新特征中一样包装一个非对象安全的特征,这样我们就可以像上面的例子那样对它执行动态操作?