将 Rayon into_par_iter().sum() 与自定义结构一起使用

Using Rayon into_par_iter().sum() with custom struct

我正在尝试使用 Rayon::prelude::into_par_iter 来总结一个结构的一堆实例。我已经为结构实现了 std::iter::Sum,但仍然 运行 出错。这是我的示例代码;

use std::iter::Sum;

use rayon::prelude::*;

pub struct TestStruct {
    val: f32,
}

impl TestStruct {
    pub fn new(v: f32) -> Self {
        Self { val: v }
    }
}

impl<'a> Sum<&'a Self> for TestStruct {
    fn sum<I>(iter: I) -> Self
    where
        I: Iterator<Item = &'a Self>,
    {
        iter.fold(Self { val: 0. }, |a, b| Self {
            val: a.val + b.val,
        })
    }
}

fn main() {
    let default_val: f32 = 1.1;
    let sum: TestStruct = (0..5).into_par_iter().map(|&default_val| {
        TestStruct::new(default_val)
    })
    .sum();

    println!("{}", sum.val);
}

有人告诉我 the trait 'std::iter::Sum' is not implemented for 'TestStruct',但我认为我正在执行它。我在这里遗漏了什么吗?

两个复杂的小问题。一种是 std::iter::Sum 定义为:

pub trait Sum<A = Self> {
    fn sum<I>(iter: I) -> Self
    where
        I: Iterator<Item = A>;
}

这里的Self是指struct得到什么实现,默认的泛型参数已经填好了,如果struct实现了Sum就不用再指定了本身。

另一个是 map 闭包参数 default_val,它是一个整数,隐藏了前一个同名的浮点数。由于 TestStruct::new 需要 f32,因此会导致类型错误。

这个有效:

impl Sum for TestStruct {
    fn sum<I>(iter: I) -> Self
    where
        I: Iterator<Item = Self>,
    {
        ...
    }
}

fn main() {
    let default_val: f32 = 1.1;
    let sum: TestStruct = (0..5)
        .into_par_iter()
        .map(|_| TestStruct::new(default_val))
        .sum();

    println!("{}", sum.val);
}