首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >退出Kernel#loop

退出Kernel#loop
EN

Stack Overflow用户
提问于 2015-01-05 02:05:33
回答 2查看 780关注 0票数 2

Kernel#loop documentation中,有一个使用break来跳出循环的例子。否则,文档将讨论如何引发StopIteration错误。

我两个都试过了:

代码语言:javascript
复制
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

输出是相同的。这两种方法之间有区别吗?我认为应该有,否则为什么要费心定义一个error类和随之而来的所有管理呢?

EN

回答 2

Stack Overflow用户

发布于 2015-01-05 02:14:30

break是ruby中的一个关键字,它终止了最内部的循环,无论是loopfor还是更多(请参阅here)。

StopIteration是一个异常,它被Kernel.loop捕获(参见here)。

因此,在您的场景中,它们是相同的,但在不同的场景中,它们的行为会有所不同:

代码语言:javascript
复制
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

下面是一个场景,当break不能使用时,可以使用StopIteration

代码语言:javascript
复制
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错误的事实:

代码语言:javascript
复制
enum = 5.times.to_enum
loop do
  p enum.next
end

将打印

代码语言:javascript
复制
0
1
2
3
4

感谢Cary提供了这个示例。

票数 3
EN

Stack Overflow用户

发布于 2015-01-05 02:53:18

break关键字有两种用法。

首先:break关键字在块中时,会导致块被传递到的方法返回。如果您将一个参数传递给break,则该方法的返回值将是该参数。下面是一个示例:

代码语言:javascript
复制
def a
  puts 'entering method a'
  yield
  puts 'leaving method a'
end

result = a { break 50 }
puts result

这将打印以下内容:

代码语言:javascript
复制
entering method a
50

第二:break关键字可能导致whileuntilfor循环终止。下面是一个示例:

代码语言:javascript
复制
i = 0
result =
  while i < 5
    i += 1
    puts i
    break 75 if i == 3
  end
puts result

这将打印以下内容:

代码语言:javascript
复制
1
2
3
75

您的Kernel#loop示例使用了第一种情况,导致loop方法返回。

据我所知,StopIteration是一个例外,它只适用于Kernel#loop。例如:

代码语言:javascript
复制
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未被捕获:

代码语言:javascript
复制
x = 0
loop.each do
  puts x
  x += 1
  raise StopIteration if x == 4
end

捕获StopIteration并退出。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27768641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档