在Ruby中传递&:method和:method作为函数参数之间的区别 [英] Difference between passing &:method and :method as function arguments in ruby
问题描述
我在理解何时使用&"符号并将符号传递给表示方法的函数方面很费劲.例如,如果我想计算范围1..10的总和,则可以执行以下操作:
I'm struggling in understanding when to use the ampersand in passing symbols to functions representing a method. For example, If I wanted to calculate the sum of the range 1..10, I could do the following:
(1..10).inject(:+)
这最初使我相信,如果您想传递符号以定义要在函数中神奇地"使用的方法,则可以将函数名称作为符号传递.但是后来我看到了类似的东西:
This originally lead me to believe that if you wanted to pass a symbol to define a method to "Magically" be used in the function, you would pass the function name as a symbol. But then I see something like this in rails:
total = Product.find(product_list).sum(&:price)
如果我理解正确,&:price与调用:price.to_proc相同.我不明白上面的工作原理.
If I understand correctly, &:price is the same as calling :price.to_proc. I don't understand how the above works.
推荐答案
在方法调用的实际参数列表中,&object
是内置语法,它将
In actual parameter list of a method call, &object
is built-in syntax, which will
- 使用
object.to_proc
将 - 将Proc作为方法的块参数传递
object
转换为Proc
- convert
object
to a Proc usingobject.to_proc
- pass the Proc as the block parameter of the method
Symbol#to_proc
将符号(例如:the_symbol)转换为proc {|obj| obj.send(:the_symbol)}
.而且,只要object
响应to_proc
方法并返回Proc,就可以使用此语法.
Symbol#to_proc
converts the symbol (eg. :the_symbol) to proc {|obj| obj.send(:the_symbol)}
. And you can use this syntax whenever object
responds to to_proc
method and returns a 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(:+)
shows that inject accepts a symbol as parameter. How the symbol is used is method specific behavior. In inject
's special case, it has the same effect as (1..10).inject{|a, b| a.send(:+, b)}
. It's just a simple, normal parameter, the effect depends on the implementation of the method that accept the symbol as parameter.
请注意,ActiveSupport中的sum
接受具有单个参数的块,其效果是"将原始序列中的值映射到新值并计算它们的总和",因此
Note that sum
in ActiveSupport accepts a block with single parameter, which has the effect "map values in the original sequence to new ones and calculate the sum of them", so
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 }
具有与以下相同的返回值,但不会产生中间临时数组:
which has the same return value as the following but won't produce intermediate temp array:
total = Product.find(product_list).map{|p| p.price}.sum
这篇关于在Ruby中传递&:method和:method作为函数参数之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!