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

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

问题描述

对于 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 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天全站免登陆