Generics 如何以通用方式定义向量(或迭代器)上的和?

Generics 如何以通用方式定义向量(或迭代器)上的和?,generics,sum,rust,Generics,Sum,Rust,我有以下sum函数,用于编译并运行良好的i32向量: fn sum_vec(s: &Vec<i64>, init: &i64) -> i64 { (*s).iter().fold(*init, |acc, &item| acc + item) } 但是我得到了以下错误 错误[E0308]:类型不匹配 -->src/lib.rs:4:42 | 4 |(*s).iter().fold(*init,| acc,&item | acc+item) |^

我有以下
sum
函数,用于编译并运行良好的
i32
向量:

fn sum_vec(s: &Vec<i64>, init: &i64) -> i64 {
    (*s).iter().fold(*init, |acc, &item| acc + item)
}
但是我得到了以下错误

错误[E0308]:类型不匹配
-->src/lib.rs:4:42
|
4 |(*s).iter().fold(*init,| acc,&item | acc+item)
|^^^^^^^^^^^^应为类型参数,找到关联的类型
|
=注意:应为'T'类型`
找到类型“::输出`
似乎必须进一步限制《公约》的实施
Add
trait,使类型
Add::Output
等于
T
。根据interwebz上的一些文档(可能是旧版本的Rust),我尝试将类型约束更改为
T:Add
,即将泛型函数声明为:

fn sum_gen_1<T: Add<T, T>>(s: &Vec<T>, init: &T) -> T
fn sum\u gen\u 1(s:&Vec,init:&T)->T
具有与以前相同的功能体。这次我犯了错误

error[E0107]:类型参数的数量错误:最多应为1,找到2
-->src/lib.rs:3:17
|
3 | fn sum_gen_1(s:&Vec,init:&T)->T{
|^^^^^^^^^^^^^最多需要1个类型参数
实现这一点的正确方法是什么?我是否应该使用不同的特征而不是
Add
?也许可以定义我自己的特征,并针对我希望我的
sum
工作的类型实施它


我注意到,这是一个似乎使我的实现变得不必要的特性。但是,它被标记为不稳定,任何尝试使用它的行为都会在使用rustc-1.0.0-beta时导致编译错误。

您几乎就得到了它。相关类型必须按名称/关键字给出,因此您正在寻找
添加

有了这一改变,您将面临这样一个问题:大量复制数字,但没有
复制
绑定。我建议以下实现:

fn sum_vec<T>(s: &[T], init: &T) -> T
where
    T: Copy + Add<T, Output = T>,
{
    s.iter().fold(*init, |acc, &item| acc + item)
}
fn sum_vec(s:&T],init:&T)->T
哪里
T:复制+添加,
{
s、 iter().折叠(*初始,|附件和项目|附件+项目)
}
&Vec
更改为
&[T]
没有效果,但它使函数更通用,并且不会丢失任何内容

另见:


    • 在看到向量的答案后,我继续为
      T
      的通用迭代器实现基本相同的函数:

      use std::ops::Add;
      
      fn sum_iter<I>(s: I, init: &I::Item) -> I::Item
      where
          I: Iterator + Clone,
          <I as Iterator>::Item: Add<I::Item, Output = I::Item> + Copy,
      {
          s.clone().fold(*init, |acc, item| acc + item)
      }
      
      使用std::ops::Add;
      fn sum_iter(s:I,init:&I::Item)->I::Item
      哪里
      I:迭代器+克隆,
      ::项目:添加+复制,
      {
      s、 clone().fold(*init,| acc,item | acc+item)
      }
      

      要在三个地方键入
      I::Item
      ::Item
      似乎有点冗长…我在中询问了这一点谢谢。这非常有用。我将我的问题扩展到迭代器,而不仅仅是向量…非常感谢您的反馈。
      use std::ops::Add;
      
      fn sum_iter<I>(s: I, init: &I::Item) -> I::Item
      where
          I: Iterator + Clone,
          <I as Iterator>::Item: Add<I::Item, Output = I::Item> + Copy,
      {
          s.clone().fold(*init, |acc, item| acc + item)
      }