“for”和“Ruby”中的“each”

我刚刚有一个关于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循环,在块完成之后,迭代器variables仍然存在。 在each循环中,除非在循环开始之前它已经被定义为局部variables,否则它不会。

除此之外, for each方法只是语法糖。

@collection nil两个循环都抛出exception:

例外:对于main:Object,未定义的局部variables或方法`@collection'

请参阅“ For循环的邪恶 ”一个很好的解释(考虑到variables范围,有一个小的区别)。

使用each被认为是更习惯于使用Ruby。

你的第一个例子,

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

比较习惯 虽然Ruby支持像whilewhile这样的循环结构,但块语法通常是首选。

另一个微妙的区别是,你在for循环中声明的任何variables都可以在循环之外使用,而迭代器中的variables是私有的。

还有一个不同..

 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

它看起来没有区别, 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 

就像贝亚德所说的,每一种都比较习惯。 它隐藏了更多的东西,不需要特殊的语言function。 每Telemachus的评论

for .. in ..设置循环的范围之外的迭代器,所以

 for a in [1,2] puts a end 

在循环结束后留下a定义。 哪里没有。 这是另一个赞成使用each一个的原因,因为临时variables的寿命较短。

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

永远不要使用它可能会导致错误。

差别是微妙的,但可能会造成巨大的错误!

不要被愚弄,这不是关于惯用代码或风格的问题。 这是避免生产代码中几乎无法追踪的错误的问题。 Ruby的实现有一个严重的缺陷,不应该使用。 始终使用each循环,永远不要使用循环。

这里是一个例子,介绍一个错误,

 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| ... } %w{foo bar quz}.each { |n| ... }打印

 foo bar quz 

为什么?

for循环中,variablesn被定义了一次,然后这个定义被用于所有的迭代。 因此,每个块在循环结束时指代具有quz值的相同的n 。 错误!

each循环中,为每次迭代定义新的variablesn ,例如在variablesn上方定义三个不同的时间。 因此,每个块都指向一个单独的具有正确值的n