Ruby:for循环和每个循环之间有什么区别?

可能重复:
对于Ruby中的每个人

假设我们有一个数组,就像

sites = %w[stackoverflow stackexchange serverfault]

有什么区别

 for x in sites do puts x end 

 sites.each do |x| puts x end 

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

关于范围界定存在细微差别,但我建议理解它,因为它揭示了Ruby的一些重要方面。

for是一种语法结构,有点类似于if 。 无论你在block中定义什么,都会在之后保持定义:

 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都是接收块的方法 。 Block引入了新的词法范围,因此无论你在其中引入什么变量,在方法完成后都不会出现:

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

我建议完全忘记,因为在Ruby中使用each都是惯用的,用于遍历可枚举。 它还通过降低副作用的可能性来更好地重新考虑函数式编程的范例。

sites.each作用于块内的x ,而如果在块外声明则将重用x 。 因此,通常最好使用each ,它最大限度地减少了大量代码的副作用。

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 > py 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 > py 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 

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