【问题标题】:Difference between block and &block in RubyRuby中block和&block的区别
【发布时间】:2009-09-06 18:04:16
【问题描述】:

为什么有时我应该在接受块的函数中使用块而其他时候 &block?

【问题讨论】:

  • 很好的问题@collimarco

标签: ruby


【解决方案1】:

block 只是一个局部变量,&block 是对传递给方法的块的引用。

def foo(block = nil)
  p block
end

foo # => nil
foo("test") # => test
foo { puts "this block will not be called" } # => nil

def foo(&block)
  p block
end

foo # => nil
foo("test") # => ArgumentError: wrong number of arguments (1 for 0)
foo { puts "This block won't get called, but you'll se it referenced as a proc." }
# => #<Proc:0x0000000100124ea8@untitled:20>

您也可以在调用方法时使用&amp;block 将proc 作为块传递给方法,这样您就可以像使用块一样使用procs。

my_proc = proc {|i| i.upcase }

p ["foo", "bar", "baz"].map(&my_proc)
# => ["FOO", "BAR", "BAZ"]

p ["foo", "bar", "baz"].map(my_proc)
# => ArgumentError: wrong number of arguments (1 for 0)

变量名block 没有什么特别的意思。如果你愿意,可以使用&amp;strawberries,& 符号是这里的关键。

您可能会发现this article 很有帮助。

【讨论】:

  • 我要补充一点:它类似于您对数组使用 splat(即 '*')运算符的方式:def foo(*args) ; other_foo(*args) ; end 将接收任意参数数组,然后将相同的数组传递给内部函数调用。有了块,你会做def foo(&amp;block) ; other_foo(&amp;block) ; end
【解决方案2】:

在参数列表中,&amp;whatever 获取传递给方法的块并将其包装在 Proc 对象中。 Proc 存储在一个名为 whatever 的变量中(当然,它可以是您在 & 号后面键入的任何名称——通常是“块”)。在方法调用之后,&amp;whatever 语法将 Proc 转换为块。所以如果你定义一个这样的方法:

def thing(&block)
  thing2 &block
end

您正在定义一个方法,该方法接受一个块,然后使用该块调用另一个方法。

【讨论】:

    【解决方案3】:

    如果你没有设置 & before 块,Ruby 将无法识别它与你传递给函数的“块”的关系。这里有一些例子。

    def f(x, block); end
    f(3) { 2+2 }    # gives an error, because "block" is a
                    # regular second argument (which is missing)
    
    def g(x, &block); end
    g(3) { 2+2 }    # legal
    
    def h(x); end
    h(3) { 2+2 }    # legal
    

    供以后在函数中使用:

    def x(&block)   # x is a 0 param function
      y(block)      # y is a 1 param function (taking one "Proc")
      z(&block)     # z is a 0 param function (like x) with the block x received
    end
    

    因此,如果您调用 z(&amp;block),它(几乎!!)与调用 z { yield } 相同:您只需将块传递给下一个函数。

    【讨论】:

      猜你喜欢
      • 2013-07-04
      • 2013-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多