我有一个关于Ruby循环的问题。这两种遍历集合的方法有区别吗?

# way 1
@collection.each do |item|
  # do whatever
end

# way 2
for item in @collection
  # do whatever
end

只是想知道这些是否完全相同,或者是否可能有细微的差异(可能在@collection为nil时)。


当前回答

(1..4).each { |i| 


  a = 9 if i==3

  puts a 


}
#nil
#nil
#9
#nil

for i in 1..4

  a = 9 if i==3

  puts a

end
#nil
#nil
#9
#9

在for循环中,局部变量在每次循环后仍然有效。在“each”循环中,局部变量在每次循环后都会刷新。

其他回答

这是唯一的区别:

每一个:

irb> [1,2,3].each { |x| }
  => [1, 2, 3]
irb> x
NameError: undefined local variable or method `x' for main:Object
    from (irb):2
    from :0

for:

irb> for x in [1,2,3]; end
  => [1, 2, 3]
irb> x
  => 3

对于for循环,迭代器变量在块完成后仍然存在。对于每个循环,它都不会,除非它在循环开始之前已经定义为局部变量。

除此之外,for只是每个方法的语法糖。

当@collection为nil时,两个循环都会抛出异常:

异常:main:Object未定义的局部变量或方法“@collection”

(1..4).each { |i| 


  a = 9 if i==3

  puts a 


}
#nil
#nil
#9
#nil

for i in 1..4

  a = 9 if i==3

  puts a

end
#nil
#nil
#9
#9

在for循环中,局部变量在每次循环后仍然有效。在“each”循环中,局部变量在每次循环后都会刷新。

看起来没有什么区别,因为它们都在下面使用。

$ irb
>> for x in nil
>> puts x
>> end
NoMethodError: undefined method `each' for nil:NilClass
    from (irb):1
>> nil.each {|x| puts x}
NoMethodError: undefined method `each' for nil:NilClass
    from (irb):4

就像贝亚德说的,每一个都更习惯。它对您隐藏了更多,并且不需要特殊的语言功能。 根据Telemachus的评论

为. .在. .将迭代器设置在循环范围之外,因此

for a in [1,2]
  puts a
end

循环结束后留下一个已定义的对象。而每个人都没有。这是支持使用each的另一个原因,因为临时变量存在的时间较短。

据我所知,使用块而不是语言内的控制结构更习惯。

还有一个不同的…

number = ["one", "two", "three"]
 => ["one", "two", "three"] 

loop1 = []
loop2 = []

number.each do |c|
  loop1 << Proc.new { puts c }
end
 => ["one", "two", "three"] 

for c in number
  loop2 << Proc.new { puts c }
end
 => ["one", "two", "three"] 

loop1[1].call
two
 => nil 

loop2[1].call
three
 => nil 

来源:http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby

想要更清楚:http://www.ruby-forum.com/topic/179264#784884