Rust有两个主要的迭代特性:标准的Iterator
用于可以按顺序遍历的东西,DoubleEndedIterator
用于可以从后面迭代的东西。
这对我来说是有意义的。在Iterator
上定义了许多有用的方法,如map
、filter
等。然后,像rfind
和rfold
这样从"返回"操作的操作,也可以说是在DoubleEndedIterator
上定义的,因为这些操作只在这样的迭代器上有意义。
然后我们有Iterator::rev
fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator, { Rev::new(self) }
rev
是在Iterator
上定义的函数,但在Self
上有一个附加约束,即它也是DoubleEndedIterator
。
在Iterator
上定义这个函数的实际好处是什么?我们只能在DoubleEndedIterator
实现者上调用它,DoubleEndedIterator
扩展Iterator
,所以我们永远不会出现实现前者而不实现后者的情况。那么为什么rev
没有像rfind
和rfold
那样定义在DoubleEndedIterator
上呢?
这允许:
- 在一个地方查看
Iterator
的所有功能(doc)。 - 在
Iterator
上使用rev()
而不需要use DoubleEndedIterator
,prelude
包含它,所以它实际上不是问题。我想通过让用户忽略DoubleEndedIterator
的存在来减少认知负荷。