2011-04-15 71 views
5

可能重复:
for vs each in RubyRuby:for循环和每个循环之间有什么区别?

比方说,我们有一个数组,像

sites = %w[stackoverflow stackexchange serverfault]

什么

for x in sites do 
    puts x 
end 
的区别

sites.each do |x| 
    puts x 
end 

他们似乎做同样的事情,对我来说,并且for循环的语法对我来说更清楚。有区别吗?在什么情况下这会是一个大问题?

+0

我查了类似的东西,但我没有看到它。 – eckza 2011-04-15 13:15:12

回答

26

有关于作用域细微的差别,但我会建议了解它以及它揭示了一些红宝石的重要方面。

for是一种语法结构,有点类似于if。不管你在for块定义,将for后以及保持定义:

sites = %w[stackoverflow stackexchange serverfault] 
#=> ["stackoverflow", "stackexchange", "serverfault"] 

for x in sites do 
    puts x 
end 
stackoverflow 
stackexchange 
serverfault 
#=> ["stackoverflow", "stackexchange", "serverfault"] 
x 
#=> "serverfault" 

在另一方面,each方法其接收的块。阻止引入新的词汇范围,让你在它推出的任何变量,方法结束后不会在那里:

sites.each do |y| 
    puts y 
end 
stackoverflow 
stackexchange 
serverfault 
#=> ["stackoverflow", "stackexchange", "serverfault"] 
y 
NameError: undefined local variable or method `y' for #<Object:0x855f28 @hhh="hello"> 
    from (irb):9 
    from /usr/bin/irb:12:in `<main>' 

我会建议忘记了for完全,如使用each是遍历枚举接口Ruby的习惯。它还通过减少副作用的机会更好地回顾功能性程序设计的范例。

+0

很好的答案 - 非常清楚和彻底的解释。非常感谢你! – eckza 2011-04-15 13:15:35

+0

+1很好的答案。 – Krule 2011-04-15 13:16:16

+0

非常有趣。我以为他们是一样的! :) – fl00r 2011-04-15 13:34:20

8

sites.each作用域x在块内,而for将重用x如果在块外部声明。一般来说,最好使用each,它将大量代码的副作用降至最低。

-1

CBZ答案是正确的。为了说明这一点,看看这个例子:

ruby-1.9.2-p180 :001 > a = %w{ blah lah kah } 
=> ["blah", "lah", "kah"] 
ruby-1.9.2-p180 :002 > x = 1 
=> 1 
ruby-1.9.2-p180 :003 > for x in a do 
ruby-1.9.2-p180 :004 >  puts x 
ruby-1.9.2-p180 :005?> end 
blah 
lah 
kah 
=> ["blah", "lah", "kah"] 
ruby-1.9.2-p180 :006 > x 
=> "kah" 
ruby-1.9.2-p180 :007 > x=1 
=> 1 
ruby-1.9.2-p180 :008 > a.each do |x| 
ruby-1.9.2-p180 :009 >  puts x 
ruby-1.9.2-p180 :010?> end 
blah 
lah 
kah 
=> ["blah", "lah", "kah"] 
ruby-1.9.2-p180 :011 > x 
=> 1 
4

CBZ的答案是正确的,但不完全的,因为有1.8.x的和1.9.x的之间的行为差​​异:

1.9.2 IRB:

ruby-1.9.2-p180 :001 > x = [1,2,3,4,5] 
=> [1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :002 > y = ["a","b"] 
=> ["a", "b"] 
ruby-1.9.2-p180 :003 > x.each do |y| 
ruby-1.9.2-p180 :004 >  p y 
ruby-1.9.2-p180 :005?> end 
1 
2 
3 
4 
5 
=> [1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :006 > y 
=> ["a", "b"] 

1.8.7 IRB:

ree-1.8.7-2011.03 :001 > x = [1,2,3,4,5] 
=> [1, 2, 3, 4, 5] 
ree-1.8.7-2011.03 :002 > y = ["a","b"] 
=> ["a", "b"] 
ree-1.8.7-2011.03 :003 > x.each do |y| 
ree-1.8.7-2011.03 :004 >  p y 
ree-1.8.7-2011.03 :005?> end 
1 
2 
3 
4 
5 
=> [1, 2, 3, 4, 5] 
ree-1.8.7-2011.03 :006 > y 
=> 5 
+0

感谢澄清。对于它的价值,我使用1.9.2。 – eckza 2011-04-15 13:56:42

相关问题