我剛剛對Ruby中的循環提出了一個問題。這兩種迭代集合的方式是否有區別?「for」vs「each」in Ruby
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
或只是想知道,如果這些是完全一樣的,如果可能有細微的差別(可能時@collection
爲零)。
我剛剛對Ruby中的循環提出了一個問題。這兩種迭代集合的方式是否有區別?「for」vs「each」in Ruby
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
或只是想知道,如果這些是完全一樣的,如果可能有細微的差別(可能時@collection
爲零)。
這是唯一的區別:
每個:
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
爲:
irb> for x in [1,2,3]; end
=> [1, 2, 3]
irb> x
=> 3
隨着for
循環中,迭代變量仍然住後的塊是完成。使用each
循環,它不會,除非在循環開始之前它已經被定義爲局部變量。
除此之外,for
只是each
方法的語法糖。
當@collection
是nil
兩個環拋出異常:
例外:未定義局部變量或方法`@collection」的主要:對象
你的第一個例子,
@collection.each do |item|
# do whatever
end
is more idiomatic。雖然Ruby支持像for
和while
這樣的循環結構,但塊語法通常是首選。
另一個細微的區別是,您在for
循環內聲明的任何變量都將在循環外部可用,而迭代器塊中的變量實際上是私有的。
據我所知,使用塊代替語言中的控制結構更具慣用性。
看起來沒有區別,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
就像貝亞德說的,每一種都更加地道。它隱藏了更多的內容,不需要特殊的語言功能。 每特勒馬庫斯的評論
for .. in ..
設置環路範圍之外的迭代器,所以
for a in [1,2]
puts a
end
離開a
循環結束之後確定。 each
沒有。這是支持使用each
的另一個原因,因爲臨時變量的壽命較短。
請參閱「The Evils of the For Loop」以獲得很好的解釋(考慮到變量作用域,有一個小差異)。
使用each
是considered more idiomatic使用Ruby。
@zachlatta:感謝您的通知。我將編輯鏈接以指向文章的webarchive.org變體! – ChristopheD 2013-04-08 22:47:17
http://graysoftinc.com/early-steps/the-evils-of-the-for-loop是新的鏈接,現在JEG2的網站重新上線了。 – pnomolos 2014-06-11 23:32:57
一個以上不同..
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
'loop1'和'loop2'未定義。 – 2014-05-03 17:20:33
答案更新!謝謝@DarekNędza – 2014-05-03 19:47:25
千萬不要使用for
它可能會導致錯誤。
區別是微妙的,但可能會導致巨大的錯誤!
不要被愚弄,這不是關於慣用代碼或樣式問題。這是避免生產代碼中幾乎無法追蹤的錯誤的問題。 Ruby的for
的實現有一個嚴重的缺陷,不應該使用。始終使用each
循環,永遠不會使用for
循環。
這裏是for
引入了一個錯誤的例子,
class Library
def initialize
@ary = []
end
def method_with_block(&block)
@ary << block
end
def method_that_uses_these_blocks
@ary.map(&:call)
end
end
lib = Library.new
for n in %w{foo bar quz}
lib.method_with_block { n }
end
puts lib.method_that_uses_these_blocks
打印
quz
quz
quz
使用%w{foo bar quz}.each { |n| ... }
打印
foo
bar
quz
爲什麼?
在for
循環中,變量n
定義了一次,然後該定義用於所有迭代。因此,每個塊指代在循環結束時具有值quz
的相同n
。錯誤!
在一個each
循環新鮮變量n
被定義爲每次迭代,例如可變n
上述定義三個獨立倍。因此,每個塊都指代具有正確值的單獨的n
。
你的意思是「方法」,而不是「功能」。 – 2016-12-23 23:40:16
@ericduminil好抓,太多polyglot,哈哈。 – akuhn 2016-12-23 23:44:09
關於可變範圍,存在一個小的差異(如yjerem,ChristopheD和Bayard提到)。 – Telemachus 2010-07-20 21:56:39
不正確,'for'不在下面使用'each'。查看其他答案。 – akuhn 2016-12-23 22:27:48
@akuhn有關進一步的說明,請參閱此[問題](http://stackoverflow.com/q/39839809/5101493)及其優秀答案。 – 2016-12-28 13:56:06