使用 std::iter::Iterator::reduce 求和的正确语法是什么?

What is the right syntax to use std::iter::Iterator::reduce for summation?

在我为此尝试过的许多代码中,我认为这是更简洁的代码:

fn summation<I>(nums: I) -> Option<I::Item>
where
    I: Iterator,
    I::Item: std::ops::Add,
{
    nums.reduce(|a, b| a + b)
}

fn main() {
    let numbers: Vec<f32> = vec![1f32, 2f32, 3f32];
    let result = summation(numbers.into_iter());
}

我的目标主要是修补 Iterator::reduce 的功能,以增加我对 Rust 的理解。

当我在 powershell 中 运行 cargo check 时,上面的代码吐出以下错误:

    Checking code_demo v0.1.0 (C:\Users\miked\git\code_demo)
error[E0308]: mismatched types
 --> src\main.rs:6:24
  |
6 |     nums.reduce(|a, b| a + b)
  |                        ^^^^^ expected std::iter::Iterator::Item, found std::ops::Add::Output
  |
  = note: expected associated type `<I as Iterator>::Item`
             found associated type `<<I as Iterator>::Item as Add>::Output`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `code_demo`

To learn more, run the command again with --verbose.

我试图复制 docs.rs 上的代码,但那里的代码片段正在使用 Ord 特质。

我也试过这个:

fn summation<I>(nums: I) -> Option<I::Item>
where
    I: Iterator,
    I::Item: std::ops::Add::Output,
{
    nums.reduce(|a, b| a + b)
}

fn main() {
    let numbers: Vec<f32> = vec![1f32, 2f32, 3f32];
    let result = summation(numbers.into_iter());
}

而运行宁cargo check会吐槽:

    Checking code_demo v0.1.0 (C:\Users\miked\git\code_demo)
error[E0404]: expected trait, found associated type `std::ops::Add::Output`
 --> src\main.rs:4:14
  |
4 |     I::Item: std::ops::Add::Output,
  |              ^^^^^^^^^^^^^^^^^^^^^ not a trait

error: aborting due to previous error

For more information about this error, try `rustc --explain E0404`.
error: could not compile `code_demo`

To learn more, run the command again with --verbose.

有没有一种方法可以为函数实现 Add 以求和 整数向量还是浮点数向量?

或者我试图做的事情是不可能的,只是使用 use std::iter::Sum;?如果是这样,那将如何实施?

谢谢。

编辑:
1st 抱歉,忘记删除通用参数 T
第二次我添加了我尝试过的其他解决方案

看来你对这个问题有了大致的了解。由于 reduce 需要 reducer 函数 returns I::Item,您需要显式设置 Add 的边界,以便保证输出与它使用的相同类型输入。您正在寻找的语法是

I::Item: std::ops::Add<Output=I::Item>

所以你的代码将编译

fn summation<I>(nums: I) -> Option<I::Item>
where
    I: Iterator,
    I::Item: std::ops::Add<Output=I::Item>
{
    nums.reduce(|a, b| a + b)
}