问题是0
。我现在还不清楚具体的规则,但我们笼统地说:0
是某种特定的整数类型,它可能与任何东西相同,也可能不同T
是。因此,编译器无法计算出参数的类型range
应该是。
您可以使用以下方法解决此问题Zero::zero https://docs.rs/num/0.1.37/num/trait.Zero.html:
fn positions<T: Integer>(start: T, step: T, len: T) -> Vec<T> {
(T::zero()..len).map(|i| start + step * i).collect()
}
这给了编译器足够的余地来推断两个参数range
属于同一类型。然而,这仍然不足以使用Range
作为迭代器:
error: no method named `map` found for type `std::ops::Range<T>` in the current scope
--> src/main.rs:8:22
|
8 | (T::zero()..len).map(|i| start + step * i).collect()
| ^^^
|
= note: the method `map` exists but the following trait bounds were not satisfied: `T : std::iter::Step`, `&'a T : std::ops::Add`, `std::ops::Range<T> : std::iter::Iterator`
不幸的是,从 Rust 1.17 开始,Step trait https://doc.rust-lang.org/std/iter/trait.Step.html不稳定,所以目前没有好的方法使用稳定的 Rust 来解决这个问题。
使用不稳定的 Rust,您可能需要实现Step
:
#![feature(step_trait)]
extern crate num;
use num::Integer;
fn positions<T>(start: T, step: T, len: T) -> Vec<T>
where T: Integer + std::iter::Step + Copy,
for<'a> &'a T: std::ops::Add<Output = T>
{
(T::zero()..len).map(|i| start + step * i).collect()
}
fn main() {
println!("{:?}", positions(10, 2, 10));
}
You also需要要求T
可以复制(或克隆,如果你愿意的话),因为Add
and Mul
按值消耗操作数,这意味着start + step * i
只能调用一次,除非需要调用多次。