【问题标题】:Ruby: What is the difference between a for loop and an each loop? [duplicate]Ruby:for 循环和 each 循环有什么区别? [复制]
【发布时间】:2023-03-09 21:18:01
【问题描述】:

可能重复:
for vs each in Ruby

假设我们有一个数组,比如

sites = %w[stackoverflow stackexchange serverfault]

有什么区别

for x in sites do
  puts x
end

sites.each do |x|
  puts x
end

?

对我来说,他们似乎在做同样的事情,for 循环的语法对我来说更清楚。有区别吗?在什么情况下这会很重要?

【问题讨论】:

  • 我检查了类似的东西,但没有看到。

标签: ruby loops foreach syntax control-flow


【解决方案1】:

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

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 是一个接收块的方法。 Block 引入了新的词法作用域,所以你在其中引入的任何变量,在方法完成后都不会存在:

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,因为在 Ruby 中使用 each 是惯用的遍历枚举。它还通过减少副作用的机会更好地尊重函数式编程的范式。

【讨论】:

  • 很好的答案 - 非常清晰和彻底的解释。非常感谢!
  • 非常有趣。我以为他们是一样的! :)
  • 这是在一次技术面试中提出的,非常好的信息!
【解决方案2】:

sites.each 作用域 x 在块内,而 for 将重用 x 如果在块外声明。一般来说,最好使用each,这样可以最大限度地减少对大量代码的副作用。

【讨论】:

    【解决方案3】:

    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 
    

    【讨论】:

    • 感谢您的澄清。对于它的价值,我使用的是 1.9.2。
    【解决方案4】:

    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 
    

    【讨论】:

      猜你喜欢
      • 2016-02-08
      • 2011-04-01
      • 1970-01-01
      • 2017-06-29
      • 1970-01-01
      • 2021-06-28
      • 2011-01-19
      • 2020-11-01
      相关资源
      最近更新 更多