我是Rust的新手,我正在努力学习迭代器 . 我正在处理的具体问题是产生三角形数字的迭代器(三角形数字为1,3,6,10,15,其中1 = 1,3 = 1,2,6 = 1 2 3等) . 我有这个创建的基础知识,如下所示:
pub struct Triangle {
cur: u32,
n: u32,
m: u32,
}
impl Iterator for Triangle {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.n == self.m {
return None;
}
self.n = self.n + 1;
self.cur = self.cur + self.n;
Some(self.cur)
}
}
一个快速可运行的例子是
let t = Triangle { cur: 0, n: 0, m: 10 };
let s: u32 = t.sum();
println!("{}", s); // prints 220
是否可以为返回类型 u32
的迭代器创建自定义求和函数 . 我希望能够使用默认的迭代器和求和函数来完成这个,而不必创建我自己的专用函数 .
我已经看过这个,我希望能做的是
impl Sum<u32> for u32 {
fn sum<I>(iter: I) -> Self where I: Triangle {
let nsum = (self.n * (self.n + 1) * (self.n + 2)) / 6;
let msum = (self.m * (self.m + 1) * (self.m + 2)) / 6;
msum - nsum
}
}
但这不起作用 . 我得到的错误是
error[E0404]: `Triangle` is not a trait
--> src/sequences.rs:61:41
|
61 | fn sum<I>(iter: I) -> Self where I: Triangle {
| ^^^^^^^^ not a trait
我可以将它从 Triangle
更改为 Iterator
,但这会阻止我访问 Triangle
结构的 m
和 n
值 . 如果有人能告诉我如何做到这一点,或者如果不可能,那就太棒了 . 我知道我可以编写自己的函数,称为 my_sum()
,但我希望能够在迭代器的上下文中完成 .
1 回答
你不能专门化
Sum
的现有实现,但你可以在你的迭代器中专门化Iterator::sum!但是,这有点棘手,因为它的返回类型是通用的 .我们不能返回固定类型(例如
u32
),因为它不会尊重Iterator
trait定义的 Contract . 我们所知道的返回类型S
就是它实现了Sum<Self::Item>
. Sum有一个返回Self
的方法sum,因此我们可以使用它生成S
类型的值 . 该方法需要一个迭代器;我们喂它Once,"an iterator that yields an element exactly once" . 由于迭代器将迭代固定次数,因此我们可以期望sum
执行固定数量的操作 .当您在发布模式下编译程序并且
S
是u32
时,整个sum
调用被优化掉,并且该函数直接返回msum - nsum
.