代码之家  ›  专栏  ›  技术社区  ›  hellvinz

Ruby while语法

  •  9
  • hellvinz  · 技术社区  · 14 年前

    ruby-1.8.7-p302 > a = %w( a b c)
     => ["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”无关?

    2 回复  |  直到 14 年前
        1
  •  13
  •   Jörg W Mittag    14 年前

    是因为 do while 语法只是语法糖,与 一个街区?

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

    这和

    在一个 虽然 循环,有两种方法可以将块与条件分离:

    1. 表达式分隔符。

    Ruby中有两个不同的表达式分隔符:

    1. ;

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

    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 在一条新的线路上 虽然 . 我只是想演示一下 虽然

    顺便说一句:把条件放在括号里是很不习惯的。代码中还有很多多余的分号。以及变量名 i 通常为索引而不是元素保留。(我通常使用 el 对于泛型元素,但我更喜欢更具语义的名称。)

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

    这不仅更容易理解它的作用(打印数组的所有元素并从中删除所有项),而且更容易编写(没有办法使终止条件出错,或者搞砸任何分配)。它也碰巧更有效:您的版本是Θ(n 2个

    事实上,你也不会这么写,因为 Kernel#puts 无论如何,已经实现了这种行为。所以,你会 真正地 写的就是这个

    puts a
    a.clear
    

    或者这个

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

    很简单。明白了。简洁的。有表现力的。快。

    比较一下:

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

        2
  •  7
  •   user229044    14 年前

    while 不需要一个块,它是一个语言构造。这个 do 是可选的:

    while (i = a.shift)
      puts i
    end