在Ruby中传递&:method和:method作为函数参数之间的区别 [英] Difference between passing &:method and :method as function arguments in ruby

查看:74
本文介绍了在Ruby中传递&:method和:method作为函数参数之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解何时使用&"符号并将符号传递给表示方法的函数方面很费劲.例如,如果我想计算范围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

  1. 使用object.to_proc
  2. object转换为Proc
  3. 将Proc作为方法的块参数传递
  1. convert object to a Proc using object.to_proc
  2. 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中传递&amp;:method和:method作为函数参数之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆