【发布时间】:2010-11-24 00:57:00
【问题描述】:
在 Perl 中,可以像这样打破外部循环:
AAA: for my $stuff (@otherstuff) {
for my $foo (@bar) {
last AAA if (somethingbad());
}
}
(语法可能错误),它使用循环标签从内循环内部中断外循环。 Ruby中有没有类似的东西?
【问题讨论】:
在 Perl 中,可以像这样打破外部循环:
AAA: for my $stuff (@otherstuff) {
for my $foo (@bar) {
last AAA if (somethingbad());
}
}
(语法可能错误),它使用循环标签从内循环内部中断外循环。 Ruby中有没有类似的东西?
【问题讨论】:
您可以考虑添加一个设置在内循环内部的标志,用于控制外循环。
'next' 外循环
for i in (1 .. 5)
next_outer_loop = false
for j in (1 .. 5)
if j > i
next_outer_loop = true if j % 2 == 0
break
end
puts "i: #{i}, j: #{j}"
end
print "i: #{i} "
if next_outer_loop
puts "with 'next'"
next
end
puts "withOUT 'next'"
end
'打破'外循环
for i in (1 .. 5)
break_outer_loop = false
for j in (1 .. 5)
if j > i
break_outer_loop = true if i > 3
break
end
puts "i: #{i}, j: #{j}"
end
break if break_outer_loop
puts "i: #{i}"
end
【讨论】:
在循环周围包裹一个内部方法可以解决问题 示例:
test = [1,2,3]
test.each do |num|
def internalHelper
for i in 0..3
for j in 0..3
puts "this should happen only 3 times"
if true
return
end
end
end
end
internalHelper
end
在这里,您可以在任何 for 循环中进行检查,并在满足条件后从内部方法返回。
【讨论】:
您想要的是非本地控制流,Ruby 有几种选择:
throw/catch
继续
优点:
GOTO 的双胞胎更好。缺点:
例外情况
优点:
缺点:
throw/catch
这是(大致)它的样子:
catch :aaa do
stuff.each do |otherstuff|
foo.each do |bar|
throw :aaa if somethingbad
end
end
end
优点:
StopIteration 异常来终止。缺点:
【讨论】:
throw/catch(甚至是例外)的控制流。他们更喜欢延续吗?您是否阅读过关于 ruby-talk 或其他内容的这种情绪?
while c1
while c2
do_break=true
end
next if do_break
end
或“break if do_break”取决于你想要什么
【讨论】:
不,没有。
您的选择是:
【讨论】:
考虑throw/catch。通常,下面代码中的外部循环将运行五次,但使用 throw 您可以将其更改为您喜欢的任何内容,并在此过程中将其中断。考虑一下这个完全有效的 ruby 代码:
catch (:done) do
5.times { |i|
5.times { |j|
puts "#{i} #{j}"
throw :done if i + j > 5
}
}
end
【讨论】:
catch、times、puts、throw、+和<=>。我不会在任何地方发送raise。
也许这就是你想要的? (未测试)
stuff.find do |otherstuff|
foo.find do
somethingbad() && AAA
end
end
find 方法一直循环,直到块返回非空值或命中列表末尾。
【讨论】:
我知道我早上会后悔,但只需使用 while 循环就可以了。
x=0
until x==10
x+=1
y=0
until y==10
y+=1
if y==5 && x==3
x,y=10,10
end
end
break if x==10
puts x
end
if y==5 && x==3 只是表达式变为真的一个示例。
【讨论】: