问题描述
对于 i32
的向量,我有以下 sum
函数,可以编译并正常工作:
I have the following following sum
function for vectors of i32
that compiles and works fine:
fn sum_vec(s: &Vec<i64>, init: &i64) -> i64 {
(*s).iter().fold(*init, |acc, &item| acc + item)
}
为了自学 Rust 泛型,我想为任何类型 T
定义相应的泛型函数,以实现 add(T, T) -> 形式的添加.T代码>.我试过了
To teach myself about Rust generics, I would like to define the corresponding generic function, for any type T
that implements addition of the form add(T, T) -> T
. I tried
use std::ops::Add;
fn sum_gen_1<T: Add>(s: &Vec<T>, init: &T) -> T {
(*s).iter().fold(*init, |acc, &item| acc + item)
}
但我收到以下错误
error[E0308]: mismatched types
--> src/lib.rs:4:42
|
4 | (*s).iter().fold(*init, |acc, &item| acc + item)
| ^^^^^^^^^^ expected type parameter, found associated type
|
= note: expected type `T`
found type `<T as std::ops::Add>::Output`
似乎必须进一步限制Add
trait 使得 Add::Output
类型等于 T
.根据在 interwebz 上找到的一些文档(可能是旧版本的 Rust),我尝试将类型约束更改为 T: Add<T, T>
,即将通用函数声明为:p>
It seems that one has to further constrain the implementation of theAdd
trait so that the type Add::Output
equals T
. Following some documentation found on the interwebz (probably for an old version of Rust), I tried changing the type constraint as to T: Add<T, T>
, i.e. declare the generic function as:
fn sum_gen_1<T: Add<T, T>>(s: &Vec<T>, init: &T) -> T
具有与以前相同的函数体.这次我得到了错误
with the same function body as before. This time I got the error
error[E0107]: wrong number of type arguments: expected at most 1, found 2
--> src/lib.rs:3:17
|
3 | fn sum_gen_1<T: Add<T, T>>(s: &Vec<T>, init: &T) -> T {
| ^^^^^^^^^ expected at most 1 type argument
实现此目的的正确方法是什么?我应该使用不同的特征而不是 Add
吗?也许定义我自己的特征并为我希望我的 sum
工作的类型实现它?
What is the proper way to accomplish this? Should I use a different trait instead of Add
? Maybe define my own trait and implement it for the types I want my sum
to work for?
我注意到这是一个特征 std::iter::AdditiveIterator
这似乎使我的实现变得不必要.但是,它被标记为不稳定,任何尝试使用它都会在使用 rustc-1.0.0-beta 时导致编译错误.
I noticed that the is a trait std::iter::AdditiveIterator
which would seem to make my implementation unnecessary. However, it is marked as unstable and any attempt to use it would cause a compile error when using rustc-1.0.0-beta.
推荐答案
你几乎明白了.关联类型必须由名称/关键字给出,因此您正在寻找 Add<T, Output = T>
.
You almost got it. Associated types must be given by name/keyword, so you're looking for Add<T, Output = T>
.
通过这种更改,您将面临一个问题,即您随意复制数字,但没有 Copy
限制.我建议以下实现:
With that change, you face the problem that you liberally copy numbers around, but there is no Copy
bound. I'd suggest the following implementation:
fn sum_vec<T>(s: &[T], init: &T) -> T
where
T: Copy + Add<T, Output = T>,
{
s.iter().fold(*init, |acc, &item| acc + item)
}
把&Vec<T>
改成&[T]
没有任何作用,但是让函数更通用,没有任何损失.
Changing &Vec<T>
to &[T]
has no effect, but it makes the function more general and loses nothing.
另见:
这篇关于如何以通用方式定义向量(或迭代器)的总和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!