rubyforloop中的最佳实践

rubyforloop中的最佳实践,ruby,for-loop,Ruby,For Loop,我遇到了三种写循环的方法 the_count = [1, 2, 3, 4, 5] 对于循环1 for number in the_count puts "This is count #{number}" end 用于循环2 the_count.each do |count| puts "The counter is at: #{count}" end 对于循环3 the_count.each {|i| puts "I got #{i}"} 是否存在一种方法比另两种方法更

我遇到了三种写循环的方法

the_count = [1, 2, 3, 4, 5]
  • 对于循环1

    for number in the_count
      puts "This is count #{number}"
    end
    
  • 用于循环2

    the_count.each do |count|
      puts "The counter is at: #{count}"
    end
    
  • 对于循环3

    the_count.each {|i| puts "I got #{i}"}
    

是否存在一种方法比另两种方法更好的情况?第一个选项与其他语言中的选项最为相似,对我来说,第三个选项看起来很无序。

第一个选项通常不被鼓励。在ruby中,可以对来自其他语言的开发人员更友好(因为他们可以识别语法),但在变量可见性方面,它的行为有点奇怪。通常,应避免在任何地方使用此变体,并仅使用其中一个块变体

其他两种变体的优点是,它适用于接受块的所有方法,例如
map
reduce
take_while
和其他方法

底部的两个变体基本上是等效的,您可以使用
每个
方法并为其提供一个块。
each
方法为数组中的每个元素调用一次块

你用哪一个取决于你的喜好。大多数人倾向于在不需要换行的简单块中使用带大括号的块。如果要在块中使用换行符,例如,如果有多条语句,则应使用
do
end
变量。这使您的代码更具可读性

关于何时应使用其中一种或另一种,还有其他一些稍有细微差别的意见(例如,有些人在编写功能块时总是使用大括号形式,即即使长了也不会影响块的外部),但如果您遵循上述建议,至少98%的ruby开发人员会阅读您的代码

因此,总之,避免使用“
”变量中的i的“
”(与“
”中的“
”、“
”中的“
”、“
”、“…”)计数相同),并始终使用块形式。对于复杂的块,使用块的
do
end
,对于简单的单行块,使用大括号形式

但是,当您使用块表单时,您应该注意链接方法时优先级的细微差异

这个

相当于

foo(bar{|i| puts i})
foo(bar) { |i| puts i }

foo bar do |i|
  puts i
end
相当于

foo(bar{|i| puts i})
foo(bar) { |i| puts i }

如您所见,在大括号表单中,块被传递到最右边的方法,而在
do
end
表单中,块被传递到最左边的方法。不过,您总是可以用括号来解决歧义。

应该注意的是,这是惯用Ruby(解决方案2和3)和performant Ruby(使用while循环,因为
for…in
在引擎盖下使用
每个
)之间的折衷,如中所述:

值得注意的是,应该提到的是,编写惯用Python和Ruby会导致比这里使用的代码慢得多的代码。射程很差。虽然循环很好


虽然人们普遍鼓励选择惯用Ruby,但在某些情况下,你可能会忽略这些建议。

惯用的方法是,如果块长,则为2;如果块短,则为3。除了上面提到的:
(1..5)。每个
1.最多(5)。每个
,等等,
(1..5)。to_a
将为你提供
[1,2,3,4,5]
@YuHao你可能会把它作为一个答案。在我看来,这就涵盖了这个问题。此外,例如,在循环结束后,变量the_count仍然可用。但在块变量中,for in使用每个在引擎盖下,这意味着
for
每个
都要慢,这与wha相反这个答案似乎是在暗示。但是如果你那么关心性能,你会选择Ruby吗?:-)请放心,Ruby永远是我的首选。这就是为什么在速度重要的时候,意识到这样的权衡是很重要的。我知道大多数时候不是这样的,而且早期优化是错误的。@awendt我认为,一般来说,建议是这样的应该始终编写适合该语言的结构。在几乎所有情况下,可理解性都胜过性能(如果不是,那么Ruby通常是错误的语言)。当然,也有一些案例偏离了规则。但这应该在每个案例中单独认真考虑,并且只有在衡量具体案例时才考虑。建议在一些奇怪的基准中使用
for
表单“因为它更快”,这可能是错误的方法。感谢非常有见地的答案!