我试图实现一个迭代器,它产生序列x ^ 2,x ^ 2 + x,x ^ 2 + 2x,x ^ 2 + 3x ...用于常量(在调用时)参数x,在Rust。
据我了解,我在实施过程中的任何时刻都必须处理self.curr
和self.next
。在我看来,序列取决于序列中项目的索引。
struct SquareMultiple {
// generates the sequence j = i^2, i^2+i, i^2+2i, i^2+3i, ...,
curr: i64,
next: i64,
}
// Implement `Iterator` for `SquareMultiple`.
// The `Iterator` trait only requires a method to be defined for the `next`
// element.
impl Iterator for SquareMultiple {
type Item = i64;
// Here, we define the sequence using `.curr` and `.next`.
// The return type is `Option<T>`:
// * When the `Iterator` is finished, `None` is returned.
// * Otherwise, the next value is wrapped in `Some` and returned.
fn next(&mut self) -> Option<I64> {
// FIXME: What to do here?
let new_next = self.curr + self.next;
self.curr = self.next;
self.next = new_next;
// Since there's no endpoint to a SquareMultiple sequence, the
// `Iterator` will never return `None`, and `Some` is always returned.
Some(self.curr)
}
}
// Returns a SquareMultiple sequence generator
fn squareseq() -> SquareMultiple {
SquareMultiple { curr: 1, next: 2 }
}
我还考虑过使用index
属性重载结构,但这似乎有点滥用这种模式。
质朴的方式是什么?
答案 0 :(得分:2)
您可以在实现Iterator
的结构中存储您想要的任何内容。对我来说,最简单的方法是存储当前值和值以增加。
struct SquareMultiple {
curr: i64,
inc: i64,
}
impl Iterator for SquareMultiple {
type Item = i64;
fn next(&mut self) -> Option<i64> {
let val = self.curr;
self.curr += self.inc;
Some(val)
}
}
impl SquareMultiple {
fn new(x: i64) -> Self {
SquareMultiple { curr: x * x, inc: x }
}
}
fn main() {
for i in SquareMultiple::new(5).take(10) {
println!("{}", i);
}
}
值得记录的是,迭代器会永远存在,因此当它超过2 ^ 63时会出现恐慌或环绕。
我喜欢这个解决方案,因为它根本不会成倍增加。出于某种原因,我的大脑认为添加比增加“更容易”。
fn main() {
let x = 5;
let clever = (0..).map(|i| x * (x + i));
for i in clever.take(10) {
println!("{}", i);
}
}
如果你需要一个单独的函数,你需要打包迭代器,因为你不能写一个闭包的类型:
fn square_multiple(x: i64) -> Box<Iterator<Item = i64>> {
Box::new((0..).map(move |i| x * (x + i)))
}
fn main() {
for i in square_multiple(5).take(10) {
println!("{}", i);
}
}
如果您需要单独的功能和最高性能(添加适当的音效),您可以创建一个新类型:
use std::ops::RangeFrom;
struct SquareMultiple {
iter: RangeFrom<i64>,
x: i64,
}
impl SquareMultiple {
fn new(x: i64) -> Self {
SquareMultiple {
iter: (0..),
x: x,
}
}
}
impl Iterator for SquareMultiple {
type Item = i64;
fn next(&mut self) -> Option<i64> {
self.iter.next().map(|i| self.x * (self.x + i))
}
}
fn main() {
for i in SquareMultiple::new(5).take(10) {
println!("{}", i);
}
}