为了账号安全,请及时绑定邮箱和手机立即绑定

Ruby中的:+和&:+是什么?

/ 猿问

Ruby中的:+和&:+是什么?

动漫人物 2019-11-11 15:47:28

我已经看过几次了,但是我不知道如何使用它们。镐说这些是特殊的快捷方式,但我找不到语法描述。


我在以下情况下看到了它们:


[1,2,3].inject(:+)

例如计算总和。


查看完整描述

3 回答

?
芜湖不芜

让我们从一个简单的例子开始。假设我们有一个大写的字符串数组:


['foo', 'bar', 'blah'].map { |e| e.upcase }

# => ['FOO', 'BAR', 'BLAH']

另外,您可以创建所谓的Proc对象(关闭):


block = proc { |e| e.upcase }

block.call("foo") # => "FOO"

您可以使用&语法将此类proc传递给方法:


block = proc { |e| e.upcase }

['foo', 'bar', 'blah'].map(&block)

# => ['FOO', 'BAR', 'BLAH']

这样做是在块上调用to_proc,然后为每个块调用它:


some_object = Object.new

def some_object.to_proc

  proc { |e| e.upcase }

end


['foo', 'bar', 'blah'].map(&some_object)

# => ['FOO', 'BAR', 'BLAH']

现在,Rails首先将to_proc方法添加到Symbol中,之后将其添加到ruby核心库中:


:whatever.to_proc # => proc { |e| e.whatever }

因此,您可以执行以下操作:


['foo', 'bar', 'blah'].map(&:upcase)

# => ['FOO', 'BAR', 'BLAH']

另外,Symbol#to_proc甚至更聪明,因为它实际上执行以下操作:


:whatever.to_proc # => proc { |obj, *args| obj.send(:whatever, *args) }

这意味着


[1, 2, 3].inject(&:+)

等于


[1, 2, 3].inject { |a, b| a + b }


查看完整回答
反对 回复 2019-11-11
?
holdtom

注入接受一个符号作为参数,该符号必须是方法或运算符的名称,这种情况是 :+


所以[1,2,3].inject(:+)被传递每个值到由符号指定的方法,因此,总结了阵列中的所有元件。


来源:https : //ruby-doc.org/core-2.5.1/Enumerable.html


查看完整回答
反对 回复 2019-11-11
?
慕容森

那不是ruby的inject定义。inject不调用to_proc,它使用带有给定符号的rb_funcall作为方法的名称。请参见enum.c中的inject_op_i。

查看完整回答
反对 回复 2019-11-11
  • 3 回答
  • 0 关注
  • 51 浏览
我要回答

相关问题推荐

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信