我正在考虑为现有的REST API实现std::iter::Iterator
。 API接受skip
和take
的参数,只需添加到查询参数(...&skip=10&take=10
)即可。
如果我可以通过发送用于迭代器skip()
和take()
的任何东西来利用这些参数,那将是很好的。由于Rust迭代器是懒惰的,感觉这是可行的。但是我在寻找实现Iterator时发现的只是next()
方法。
例:
let result = api.search("something").skip(5).take(10).collect();
// In my iterator implementation I'd like to make the following request:
// https://my.api.endpoint/?search=something&skip=5&take=10
Iterator
特征只有一个必需的方法,即next()
方法。必须为实现特征的所有类型实现此方法。 Iterator
特性的所有其他方法都是提供的方法。它们具有默认实现,您不必实现它们,但仍允许您为特定类型覆盖它们。
但是,您无法更改skip()
和take()
的声明:
fn skip(self, n: usize) -> Skip<Self> where Self: Sized;
fn take(self, n: usize) -> Take<Self> where Self: Sized;
所以这些方法使用旧的迭代器,并分别返回类型为std::iter::Skip<Self>
或std::iter::Take<Self>
的新迭代器。在调用其中一个方法之后,您将无法控制链中第二个方法的语义,因为该方法将从标准库而不是您的自定义类型调用这两种类型之一,因此您将最终调用该方法的默认实现。
你可以通过覆盖迭代器上的skip()
来使nth()
主要工作,因为Skip
和Take
的实现将nth()
转发到底层迭代器,但是使take()
正常工作是不可能的。
我建议分离构建查询的API部分并迭代结果。对于后者,Iterator
特性很好,但对于前者,您应该定义一个自定义界面。