Ruby语法

有人为什么我这样写:

ruby-1.8.7-p302 > a = %w( abc) => ["a", "b", "c"] ruby-1.8.7-p302 > while (i = a.shift) do; puts i ; end a b c => nil 

这看起来像是通过一个块来。 并不是:

 while(i = a.shift) { puts i; } 

是因为while语法的“do”只是语法糖而且与块的“do”无关?

是因为while语法的做法只是语法糖而且与块的do无关?

或多或少,是的。 这不是语法糖,它只是一个内置的语言结构,如defclass ,正如@meagar已经写过的那样。

它与块的作用无关,除了关键字很昂贵,因此重用关键字是有道理的。 (“昂贵”我的意思是他们限制程序员的表现力。)

while循环中,有两种方法可以将块与条件分开:

  1. do关键字和
  2. 表达式分隔符。

反过来,Ruby中有两个不同的表达式分隔符:

  1. 分号;
  2. 换行符

因此,以下所有三个都是有效的:

 while i = a.shift do puts i end # do while i = a.shift; puts i end # semicolon while i = a.shift puts i end # newline 

[显然,最后一个不会这样写,你会把end放在一个新的行上,缩进以匹配while 。 我只是想certificate分离while循环部分所需的最小值。]

顺便说一句:将条件括在括号中是非常不恰当的。 你的代码中还有很多多余的分号。 变量名称i通常保留给索引,而不是元素。 (我通常使用el作为通用元素,但我更喜欢更多的语义名称。)

手动迭代集合也非常不恰当。 你的代码写得好得多

 a.each(&method(:puts)).clear 

不仅更容易理解它的作用(打印数组的所有元素并从中删除所有项目),它也更容易编写(没有办法让终止条件错误,或搞砸了任何作业) )。 它也恰好更有效:你的版本是Θ(n 2 ),这个是Θ(n)。

实际上,这也不是你如何写它,因为Kernel#puts已经实现了这种行为。 所以,你真正要写的就是这个

 puts a a.clear 

或许这个

 a.tap(&method(:puts)).clear 

[注意:这最后一个不是100%相同。 它打印一个空数组的换行符,所有其他的都不打印。]

简单。 明确。 简洁。 表现力。 快速。

比较一下:

 while (i = a.shift) do; puts i ; end 

我实际上必须多次运行才能100%清楚它的作用。

while没有阻止,但它是一种语言结构。 这是可选的:

 while (i = a.shift) puts i end