我正在使用一些迭代器,在这里我必须沿着这些行执行一些操作(enum
是一个枚举器)
enums_with_zero << enum.rewind if enum.peek == 0
它通常工作正常,但这是在已经对枚举调用了
#next
几次之后。问题是enum
可能在末尾,并且有几个值传递给enum
,我遇到了enum.peek
引发StopIteration
的问题,因为enum
已经完成。有没有一种方法可以让我在调用它之前检查enum.peek
或enum.next
是否会导致StopIteration
。比如会有这种行为的东西?class Enumerator
def has_next?
begin
peek && true
rescue StopIteration
false
end
end
end
最佳答案
您可以显式地rescue
这个StopIteration
,但也有这样一种想法,即loop
方法通过退出循环在内部挽救一个StopIteration
异常。(在loop
内部,raise StopIteration
具有与break
相同的效果)
当您试图从结尾偷看时,此代码只是退出循环:
a = %w(a b c d e).to_enum
loop do
print a.peek
a.next
end
代码输出
abcde
。(它也可以透明地升起和救出StopIteration
)因此,如果您想在尝试查看结尾时忽略
StopIteration
异常,只需使用loop
。当然,一旦你偷看了结尾,你就会被甩出圈外。如果不需要,可以使用
while
和rescue
自定义行为。例如,如果要避免在浏览结束时退出,并在使用next
遍历结束时退出,可以执行以下操作:a = %w(a b c d e).to_enum
while true
begin
print a.peek
rescue StopIteration
print "\nTried to peek past the end of the enum.\nWe're gonna overlook that.\n"
end
x = a.next rescue $!
break if x.class == StopIteration
end
p 'All done!'
循环中的最后两行执行与此相同的操作,您可以改为使用:
begin
a.next
rescue StopIteration
break
end
需要指出的一点是,处理
StopIteration
是ruby处理到达迭代器末尾的预期方式。引用matz的书《ruby编程语言:外部迭代器的使用非常简单:每次需要另一个
元素。当没有其他元素时,
next
将引发一个next
异常。这似乎不寻常,对预期的终止提出了一个异常
情况而不是意外的和特殊的事件。(
StopIteration
是后代注意这是唯一的例外
名称中没有“error”一词的类)。
外部迭代技术。通过将循环终止视为异常,它使
循环逻辑非常简单;不需要检查
StopIteration
对于特殊的迭代结束值,不需要调用StandardError
调用IndexError
之前的谓词。关于ruby - 是否有内置方法来检查#next或#peek是否会引发StopIteration?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57963765/