我在努力理解何时使用&符号将符号传递给表示方法的函数。例如,如果我想计算范围1..10的总和,我可以执行以下操作:
(1..10).inject(:+)
这最初让我相信,如果你想传递一个符号来定义一个方法以在该函数中使用“魔法”,你可以将函数名称作为符号传递。但后来我在rails中看到了这样的东西:
total = Product.find(product_list).sum(&:price)
如果我理解正确,&:price与调用:price.to_proc相同。我不明白上面是如何运作的。
答案 0 :(得分:4)
在方法调用的实际参数列表中,&object
是内置语法,
object
object.to_proc
转换为Proc
Symbol#to_proc
将符号(例如:the_symbol)转换为proc {|obj| obj.send(:the_symbol)}
。只要object
响应to_proc
方法并返回Proc,就可以使用此语法。
abc = "aha~"
class << abc
def to_proc
proc {|obj| obj.to_i * 2 }
end
end
p ["1", "2", "3"].map(&abc)
#=> [2, 4, 6]
(1..10).inject(:+)
显示inject接受符号作为参数。如何使用符号是特定于方法的行为。在inject
的特殊情况下,它与(1..10).inject{|a, b| a.send(:+, b)}
具有相同的效果。它只是一个简单的普通参数,效果取决于接受符号作为参数的方法的实现。
请注意,ActiveSupport中的sum
接受具有单个参数的块,其效果为“将原始序列中的值映射到新序列并计算它们的总和”,因此< / p>
total = Product.find(product_list).sum(&:price)
等同于
total = Product.find(product_list).sum(&proc{|p| p.send(:price)})
# or you may write
total = Product.find(product_list).sum{|p| p.price }
具有与以下相同的返回值但不会产生中间临时数组:
total = Product.find(product_list).map{|p| p.price}.sum