传递&:方法和:方法作为ruby中的函数参数之间的区别

我正在努力理解何时使用&符号将符号传递给表示方法的函数。 例如,如果我想计算范围1..10的总和,我可以执行以下操作:

(1..10).inject(:+)

这最初让我相信,如果你想传递一个符号来定义一个方法,以便在函数中使用“Magically”,你可以将函数名称作为符号传递。 但后来我在rails中看到了这样的东西:

total = Product.find(product_list).sum(&:price)

如果我理解正确,&:price与调用:price.to_proc相同。 我不明白上面的工作原理。

在方法调用的实际参数列表中, &object是内置语法,它将是

  1. 使用object.to_procobject转换为Proc
  2. 将Proc作为方法的块参数传递

Symbol#to_proc将符号(例如:the_symbol)转换为proc {|obj| obj.send(: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)}具有相同的效果 (1..10).inject{|a, b| a.send(:+, b)} 。 它只是一个简单的,正常的参数,效果取决于接受符号作为参数的方法的实现。

请注意,ActiveSupport中的sum接受具有单个参数的块,其效果是“ 将原始序列中的值映射到新序列并计算它们的总和 ”,因此

 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 
Interesting Posts