Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby &引用;至于;vs";每一个;红宝石色_Ruby_Loops_Foreach_Iteration_Each - Fatal编程技术网

Ruby &引用;至于;vs";每一个;红宝石色

Ruby &引用;至于;vs";每一个;红宝石色,ruby,loops,foreach,iteration,each,Ruby,Loops,Foreach,Iteration,Each,我刚才问了一个关于Ruby中循环的快速问题。这两种迭代集合的方法有区别吗 # way 1 @collection.each do |item| # do whatever end # way 2 for item in @collection # do whatever end 只是想知道它们是否完全相同,或者是否存在细微差异(可能是在@collection为零时)。您的第一个示例 @collection.each do |item| # do whatever end 。虽然

我刚才问了一个关于Ruby中循环的快速问题。这两种迭代集合的方法有区别吗

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

# way 2
for item in @collection
  # do whatever
end
只是想知道它们是否完全相同,或者是否存在细微差异(可能是在
@collection
为零时)。

您的第一个示例

@collection.each do |item|
  # do whatever
end
。虽然Ruby支持循环结构,如
for
While
,但块语法通常是首选的


另一个细微的区别是,在
for
循环中声明的任何变量都将在循环外可用,而迭代器块中的变量实际上是私有的。

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

看起来没有区别,
for
使用下面的每个

$ 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的评论

用于。。in.
将迭代器设置在循环范围之外,因此

for a in [1,2]
  puts a
end
在循环完成后留下定义的
a
。其中as
每个
都没有。这是支持使用
每个
的另一个原因,因为temp变量的寿命较短。

请参阅“”,以获得更好的解释(考虑变量范围有一个小差异)


使用
每个
都使用Ruby。

这是唯一的区别:

每个:

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
用于:

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
循环,迭代器变量在块完成后仍然有效。对于
每个
循环,它不会,除非它在循环开始之前已经定义为局部变量

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

@collection
nil
时,两个循环都会引发异常:

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

还有一个不同的

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 
number=[“一”、“二”、“三”]
=>[“一”、“二”、“三”]
loop1=[]
loop2=[]
编号:每个do | c|
循环1[“一”、“二”、“三”]
对于c的数字
循环2[“一”、“二”、“三”]
loop1[1]。调用
二
=>零
loop2[1]。调用
三
=>零
资料来源:


更清楚地说:

永远不要使用
for
它可能会导致几乎无法追踪的错误

不要被愚弄了,这与惯用代码或样式问题无关。Ruby的
for
实现存在严重缺陷,不应使用

下面是一个示例,
for
引入了一个bug

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
使用
%w{foo-bar-quz}。每个{n |…}
打印

foo
bar
quz
为什么?

for
循环中,变量
n
只定义一次,然后一个定义用于所有迭代。因此,在循环结束时,每个块都引用相同的
n
,其值为
quz
。臭虫


每个
循环中,为每个迭代定义一个新变量
n
,例如,在上面,变量
n
被定义三次。因此,每个块都使用正确的值引用一个单独的
n

我只想就Ruby中的for-in循环提出一个具体的观点。它看起来像是一个类似于其他语言的构造,但实际上它是一个类似于Ruby中其他循环构造的表达式。事实上,for和each迭代器一样使用可枚举对象

传递给for in的集合可以是具有each迭代器方法的任何对象。数组和散列定义了每个方法,许多其他Ruby对象也定义了。for/in循环调用指定对象的each方法。当迭代器生成值时,for循环将每个值(或每组值)分配给指定的变量(或多个变量),然后执行主体中的代码

这是一个愚蠢的示例,但说明了for in循环与任何具有each方法的对象一起工作的要点,就像each迭代器所做的那样:

class Apple
  TYPES = %w(red green yellow)
  def each
    yield TYPES.pop until TYPES.empty?
  end
end

a = Apple.new
for i in a do
  puts i
end
yellow
green
red
=> nil
现在是每个迭代器:

a = Apple.new
a.each do |i|
  puts i
end
yellow
green
red
=> nil
正如您所看到的,这两种方法都响应于each方法,从而将值返回到块。正如这里的每个人所说的,在for-in循环中使用each迭代器是绝对可取的。我只是想让大家明白,for-in循环没有什么神奇之处。它是一个表达式,调用集合的每个方法,然后将其传递给其代码块。因此,这是一种非常罕见的情况,您需要在中使用它。几乎总是使用each迭代器(增加了块范围的好处)


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

关于变量范围有一个小的区别(如yjerem、ChristopheD和Bayard所提到的)。不正确,
for
不使用下面的每个
。请参阅其他答案。@akuhn如需进一步澄清,请参阅此答案及其两个优秀答案。@zachlatta:谢谢通知。我将编辑链接,指向文章的webarchive.org变体!是新的链接,现在JEG2的网站又重新上线了。有没有一个好的理由让x留在for的案例中,或者这是一个糟糕的设计:P?在我看来,与大多数其他语言相比,这似乎是不直观的。@cyc115
x
之所以保留在for场景中,是因为(一般来说)关键字不会创建新的作用域。如果、除非、开始、for、while等都在当前范围内工作<代码>#但每个
都接受一个块。块总是在当前作用域的顶部添加它们自己的作用域。这意味着在块中声明一个新变量(因此是一个新范围)将无法从块外访问,因为该附加范围在块外不可用。
直到
实际上有一些非常具体的用途,无法使用