在Kernel#loop documentation中,有一个示例使用break
来突破循环。否则,文档会讨论如何发生StopIteration
错误。
我试过了两个:
i=0
loop do
puts i
i+=1
break if i==10
end
i=0
loop do
puts i
i+=1
raise StopIteration if i==10
end
输出相同。两种方法之间是否存在差异?我认为应该有,否则为什么要费心定义一个错误类和随之而来的所有管理?
答案 0 :(得分:3)
break
是ruby中的关键字,它终止了最内部的循环,无论是loop
还是for
,还有一些(参见here)。
StopIteration
是一个例外,由Kernel.loop
捕获(请参阅here)。
因此,在您的方案中,它们是相同的,但在不同的情况下,它们将采取不同的行动:
puts "first run"
for i in 0..20 do
puts i
break if i==10
end
puts "first done"
puts "second run"
for i in 0..20 do
puts i
raise StopIteration if i==10
end
puts "second done" # <= will not be printed
以下是StopIteration
无法使用break
的情况:
puts "first run"
def first_run(i) # will not compile
puts i
break if i==10
end
i=0
loop do
first_run(i)
i+=1
end
puts "first done"
puts "second run"
def second_run(i)
puts i
raise StopIteration if i==10
end
i=0
loop do
second_run(i)
i+=1
end
puts "second done"
这是另一个用例,它使用Enumerator.next
在枚举器到达结束时抛出StopIteration
错误的事实:
enum = 5.times.to_enum
loop do
p enum.next
end
将打印
0
1
2
3
4
感谢Cary这个例子。
答案 1 :(得分:1)
break
关键字有两种用途。
首先:break
关键字在块中时,会导致传递块的方法返回。如果将参数传递给break
,则该方法的返回值将是该参数。这是一个例子:
def a
puts 'entering method a'
yield
puts 'leaving method a'
end
result = a { break 50 }
puts result
这将打印:
entering method a
50
第二:break
关键字可以导致while
,until
或for
循环终止。这是一个例子:
i = 0
result =
while i < 5
i += 1
puts i
break 75 if i == 3
end
puts result
这将打印:
1
2
3
75
Kernel#loop
的示例使用了第一种情况,导致loop
方法返回。
StopIteration
是一个例外,就我所知,仅与Kernel#loop
一起使用。例如:
infinite_loop = Enumerator.new do |y|
i = 0
while true
y << i
i += 1
end
end
infinite_loop.each do |x|
puts x
raise StopIteration if x == 4
end
失败,因为StopIteration
未被捕获,但是:
x = 0
loop.each do
puts x
x += 1
raise StopIteration if x == 4
end
抓住StopIteration
并退出。