Ruby中循环的最佳实践

7

我发现有三种编写循环的方式。

the_count = [1, 2, 3, 4, 5]
  • for loop 1

    for number in the_count
      puts "This is count #{number}"
    end
    
  • for loop 2

    the_count.each do |count|
      puts "The counter is at: #{count}"
    end
    
  • for loop 3

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

有哪些情况下,一种方式比其他两种更好或是更佳的实践方法呢?第一种方式最类似于其它语言中的写法,而对我来说,第三种方式看起来无序。


4
如果块很长,惯用的方式是用2,如果块很短,就用3。 - Yu Hao
2
除了上面提到的内容之外:(1..5).each1.upto(5).each 等等。并且,(1..5).to_a 将会给你 [1,2,3,4,5] - Aleksei Matiushkin
@YuHao 你可以把那个作为答案发布。在我看来,那已经回答了这个问题。 - AJFaraday
1
此外,在 for in 的示例中,变量 the_count 在循环结束后仍然可用。但在块变体中不行。 - jazzytomato
2个回答

15

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

另外两种变体的优点是,它们对于接受块的所有方法都起作用,例如mapreducetake_while等。

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

您使用哪种取决于个人喜好。大多数人倾向于使用带花括号的简单块,这些块不需要换行符。如果您想在块中使用换行符,例如如果您有多个语句,则应使用do...end变体。这使您的代码更易读。

还有其他稍微微妙的意见,关于何时应该使用其中之一(例如,某些人在编写功能块时总是使用花括号形式,即那些即使更长也不会影响块外部的块),但是如果您遵循上述建议,您将取悦至少98%的所有阅读您代码的Ruby开发人员。

因此,在结论中,避免使用for i in ...变体(同样适用于whileuntil等),并始终使用块形式。对于复杂的块,请使用do...end块,对于简单的单行块,请使用花括号形式。

当您使用块形式时,您应该注意在链接方法时优先级的轻微差异。

这个

foo bar { |i| puts i }

等同于

foo(bar{|i| puts i})

同时

foo bar do |i|
  puts i
end

等价于

foo(bar) { |i| puts i }

如您所见,在花括号形式中,代码块会传递给最右边的方法,而在 do...end 形式中,代码块会传递给最左边的方法。不过,您总是可以用括号消除歧义。


非常感谢您提供如此深入的答案! - Kevinvhengst

0

需要注意的是,这是在Ruby惯用法(解决方案2和3)和Ruby性能(使用while循环,因为for ... in在底层使用each)之间的权衡,正如另一种语言速度测试:计算质数所指出的:

值得注意的是,写惯用的Python和Ruby代码比这里使用的代码慢得多。范围不好,while循环好。

虽然通常鼓励选择惯用的Ruby,但在某些情况下,忽略该建议是完全有效的。


7
“for in” 在内部使用“each”。 - jazzytomato
这意味着foreach更慢,与这个答案所暗示的相反。 - sawa
好的,我已经将它纳入我的答案中。感谢您指出这一点。我想到的是 while 而不是 for in。我的观点仍然成立:默认情况下使用惯用的 Ruby,但要注意它的速度较慢。 - awendt
3
如果你很关注性能,你会选择 Ruby 吗? :-) - jazzytomato
2
放心,Ruby总是我的首选。这就是为什么当速度很重要时,意识到这样的权衡非常重要。我知道大多数情况下不需要优化,过早地进行优化是错误的。 - awendt
1
@awendt 我认为,一般建议是始终编写符合语言习惯的结构。在几乎所有情况下,可读性优先于性能(如果不是这样,那么 Ruby 往往也是错误的语言选择)。当然,也有例外情况,但必须在每个具体情况下认真考虑,并且仅在测量具体案例时才进行偏离规则的操作。建议使用 for 形式“因为它更快”在某些奇怪的基准测试中可能是错误的方法。 - Holger Just

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接