如何在闭包(Proc、lambda)中“打破”外部循环?

7

loop { break } can work fine, but

block = Proc.new { break }
# or
# block = lambda { break }
loop(&block) # => LocalJumpError: break from proc-closure

在块变量中使用break是否可行?

更新:

以下是一个例子,以进一步说明:

def odd_loop
    i = 1
    loop do
        yield i
        i += 2
    end
end

def even_loop
    i = 2
    loop do
        yield i
        i += 2
    end
end

# This work
odd_loop do |i|
    puts i
    break if i > 10
end

# This doesn't work
break_greater_10 = Proc.new do |i|
    puts i
    break if i > 10
end

odd_loop(&break_greater_10) # break from proc-closure (LocalJumpError)
even_loop(&break_greater_10) # break from proc-closure (LocalJumpError)

据我理解,Proc.new应该与块相同(它可以从块中返回一个函数),但我不明白为什么无法退出循环。

P.S. 很抱歉我的英语不好 >~<


你想通过这个实现什么目标? - Sergio Tulentsev
什么时候使用Lambda,什么时候使用Proc.new? - tokland
@Sergio 看更新,@tokland 我知道 Proc.newlambda 的区别,我在问 closure 中的 break - Steely Wing
2个回答

7
为了解决这个问题,您可以:
raise StopIteration

这对我很有帮助。

1
+1 它不仅能够正常工作,而且在 Ruby 文档示例 中还被用于停止 loop - Kelvin

3
为了退出代码块,你可以使用 next 关键字。
def foo
  f = Proc.new {next ; p 1}
  f.call
  return 'hello'
end

puts foo     # => 'hello' , without 1

在编程中,“break”语句跳出外部循环与从块中返回是不同的。 - Steely Wing
2
在您的情况下,您可以使用 lambda 并使用 return,我认为 next 不适合这种情况(虽然它可以工作)。 - Steely Wing
这实际上不能像提问者所要求的那样停止一个“循环”。 - Kelvin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接