0

我正在尝试使用 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',但我认为我正在实施它。我在这里错过了什么吗?

4

1 回答 1

1

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

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

这里Self指的是struct得到了实现,默认的泛型参数已经填好了。如果是自己实现的,就不需要再指定了Sum

另一个是map闭包参数default_val,它是一个整数,遮蔽了前一个具有相同名称的浮点数。由于TestStruct::new期望 a 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);
}
于 2019-12-05T14:55:36.500 回答