我有一些实现的东西,std::iter::Iterator我想知道是否有> 0元素.这样做的标准方法是什么?count() > 0看起来太贵了.
我看到两个候选人:any(|_| true)而且nth(0).is_some(),但是我应该选择哪一个,以便未来的读者能够理解我在这里检查的内容?
She*_*ter 11
我会写的iter.next().is_some().
但是,您需要注意这样做会推进迭代器.
fn main() {
let scores = [1, 2, 3];
let mut iter = scores.iter();
println!("{}", iter.next().is_some()); // true
println!("{}", iter.next().is_some()); // true
println!("{}", iter.next().is_some()); // true
println!("{}", iter.next().is_some()); // false
}
Run Code Online (Sandbox Code Playgroud)
在很多情况下我会使用Peekable:
fn main() {
let scores = [1, 2, 3];
let mut iter = scores.iter().peekable();
println!("{}", iter.peek().is_some()); // true
println!("{}", iter.peek().is_some()); // true
println!("{}", iter.peek().is_some()); // true
println!("{}", iter.peek().is_some()); // true
}
Run Code Online (Sandbox Code Playgroud)
所以未来的读者可以在视线中理解
我将在迭代器上添加一个名为的方法is_empty.
小智 5
实行规范的方法is_empty对Iterator不这样做.一个Iterator是懒惰的,所以根据定义,不知道它是否还有迭代的元素.
从逻辑上讲,迭代器似乎应该很容易知道它是否还有更多的元素,但如果它的大小已知,则只能是这种情况(没有迭代).事实上,ExactSizeIterator实现了is_empty.
要检查是否Iterator是空的,你必须尝试迭代,并查看是否收到了None,但是(如@Shepmaster提到的),你只能这样做没有推进Iterator,当你有一个Peekable Iterator.你可以peek()在下一个元素并检查它是否is_none():
let mut iterator = vec![1,2,3].into_iter().peekable();
println!("is_empty: {}", iterator.peek().is_none());
Run Code Online (Sandbox Code Playgroud)
考虑到在实施时,这一点更为明显Iterator,一个只需要提供一个next返回两个函数Some或None指示进一步元素是否存在.我们可以提供一个next随机决定下一个元素是否存在的实现,这清楚地表明我们无法知道next我们的迭代器是否为空:
struct RandomThings {}
impl Iterator for RandomThings {
type Item = bool;
fn next(&mut self) -> Option<bool> {
let has_next = rand::random::<bool>();
if has_next {Some(true)} else {None}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,创建PeekableIterator和调用.peek().is_none()实际上是非常明确的,未来的读者应该很容易理解.如果您只处理已知大小的迭代器,那么您可以进一步限制类型ExactSizeIterator并使用is_empty.如果你要is_empty为普通人添加,Iterator你只会隐藏这样一个事实,即next必须调用它的函数来确定它是否为空.
| 归档时间: |
|
| 查看次数: |
496 次 |
| 最近记录: |