如何以一般方式定义向量(或迭代器)上的总和? [英] How to define sum over vectors (or iterators) in a generic way?

查看:71
本文介绍了如何以一般方式定义向量(或迭代器)上的总和?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于具有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泛型的知识,我想为实现添加add(T, 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特征,以便类型Add::Output等于T.遵循在interwebz上找到的一些文档(可能是Rust的旧版本)之后,我尝试将类型约束更改为T: Add<T, T>,即将通用函数声明为:

It seems that one has to further constrain the implementation of the Add 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.

另请参阅:

这篇关于如何以一般方式定义向量(或迭代器)上的总和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆