< 返回版块

hzqd 发表于 2021-03-24 13:55

直接上代码:

use rayon::prelude::*;

fn main() {                     // 这里 i 的类型是 Vec<&i32>
    vec![1,2,3].into_par_iter().filter(|i| *i == 2).collect::<Vec<_>>();
}

trait IterExt<T> {
    fn filter(self, f: impl Fn(&T) -> bool + Sync + Send) -> Vec<T> where T: Sync;
}

impl<T> IterExt<T> for Vec<T> {//但这里的闭包要求传 &&T
    fn filter(self, f: impl Fn(&T) -> bool + Sync + Send) -> Vec<T> where T: Sync {
        self.into_par_iter().filter(f).collect()
    }
}

获得错误信息:

1. expected a `Fn<(&&T,)>` closure.
2. the method `collect` exists but the trait bounds were not satisfied.

如代码所示,同样都是 into_par_iter,但 main 函数中 filter 的 Vec 里面只有一个 &,而下面自己写的函数却要两个。这不仅造成了 the trait FromParallelIterator<&T> is not implemented for Vec<T>,(如果把函数返回写成Vec<&T>)还会导致返回的Vec内部是带引用的数据(有时多嵌套几层,还会出现函数返回Vec<&&T>)。

为什么这个闭包参数需要 &&T ?有没有什么办法只要一个 & 并返回 Vec<T>

评论区

写评论
chiyu 2021-03-24 15:27
trait IterExt<T> {
    fn filter(self, f: impl Fn(&T) -> bool + Sync + Send) -> Vec<T>
    where
        T: Send;
}

impl<T> IterExt<T> for Vec<T> {
    fn filter(self, f: impl Fn(&T) -> bool + Sync + Send) -> Vec<T>
    where
        T: Send,
    {
        self.into_par_iter().filter(f).collect()
    }
}

Send 约束

1 共 1 条评论, 1 页