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)
}