如果您不想使用计数器或生成的偏移量,您可以执行如下操作。
people = %w|Lily Bob Suzie|
#=> ["Lily", "Bob", "Suzie"]
enum = people.each.with_index(1)
#=> #<Enumerator: #<Enumerator: ["Lily", "Bob", "Suzie"]:
# each>:with_index(1)>
loop do
name, nbr = enum.next
print "name=#{name}, nbr=#{nbr} is "
puts (enum.peek rescue nil) ? "not last" : "last"
end
displays
name=Lily, nbr=1 is not last
name=Bob, nbr=2 is not last
name=Suzie, nbr=3 is last
See 枚举器#next https://ruby-doc.org/core-2.6.3/Enumerator.html#method-i-next and 枚举器#peek https://ruby-doc.org/core-2.6.3/Enumerator.html#method-i-peek. peek
如果有,则返回要生成的下一个元素,否则会引发StopInteration
例外(即,如果之前的next
生成最后一个元素)。我用过内联rescue
返回条款nil
if peek
引发异常。
只为营救StopInteration
产生的异常peek
(并且还允许people
包括对象false
and nil
,尽管这与当前上下文无关),我们可以使用begin/rescue/end
构造:
enum = people.each.with_index(1)
loop do
print "name=%s, nbr=%d is " % enum.next
begin
enum.peek
puts "not last"
rescue StopIteration
puts "last"
end
end
我们依靠enum.next
生成一个StopIteration
当枚举器生成所有元素后执行该异常。内核#循环 https://ruby-doc.org/core-2.6.3/Kernel.html#method-i-loop通过跳出循环来响应该异常。是因为enum.next
不能在begin/rescue/end
clause.