&的含义在参数中

时间:2014-02-20 02:43:16

标签: ruby block

我看到这个代码的方法与each相同,只是它收到一个块来对每个项目运行一些测试:

  def every?(&predicate)
    predicate = lambda { |item| item } if predicate.nil?
    each do |item|
      return false if !predicate.call(item)
    end
    true
  end

为什么参数中有&,它有什么作用?有什么用途?

3 个答案:

答案 0 :(得分:3)

有时在参数列表中,您会看到类似

的内容
def foo(&block)
  logic_with block
end

这只是意味着参数期望一个块 - 在你的例子中。

&predicate只是意味着将块作为参数传递,我们将其分配给局部变量predicate

如果谓词为nil,方法的第一行将新的lamda赋给谓词变量,你可以很好地理解这一点。

进一步阅读这里有关于块,触发器和lambdas的好帖子:http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/

按照下面的sawa说明编辑。

我的看法是你想要一个简单的解释,如果你看到&在这种情况下,它意味着一个块是预期的。

如果您想具体了解&运营商本身实际上做了什么,请在此处发布一篇好文章:http://ablogaboutcode.com/2012/01/04/the-ampersand-operator-in-ruby/

正如sawa所提到的,它与在传入块上调用to_proc非常相似。从我链接到的帖子,更详细地说:

  • 如果object是一个块,它会将块转换为一个简单的proc。
  • 如果object是Proc,它会在保留lambda的同时将对象转换为块?对象的状态。
  • 如果object不是Proc,它首先在对象上调用#to_proc,然后将其转换为块。

答案 1 :(得分:3)

两个运算符*&交换Ruby对象和非对象。

  • 操作符*前置于逗号分隔对象列表(不是对象),将其转换为数组(对象)。

    *("foo", "bar", "baz") # => ["foo", "bar", "baz"]
    
  • 对象前面的运算符*通过应用to_a将其转换为数组,然后将其转换为逗号分隔对象列表。

    *["foo", "bar", "baz"] # => ("foo", "bar", "baz")
    *nil                   # => *[] # => ()
    
  • 操作符&前置于块(不是对象)将其转换为proc(对象)。

    &{|e| puts e}          # => ->(e){puts e}
    
  • 对象前面的运算符&通过应用to_proc将其转换为proc,然后应用到块中。

    &->(e){puts e}         # => {|e| puts e}
    &:foo                  # => &->(e){e.foo} # => {|e| e.foo}
    

当参数位置有&时,&会附加到一个块,因此上面的第三种情况适用。该块变为proc。

答案 2 :(得分:2)

在方法定义的上下文中,将一个&符号放在最后一个参数的前面表示一个方法可能会占用一个块并给我们一个名称来引用方法体内的这个块。

当我感到困惑时,我经常会提到this post