使用符号来引用 Ruby 中的块,例如:+, :-, :*

Using symbols to reference blocks in Ruby e.g. :+, :-, :*

我正在学习符号在 Ruby 中的使用,并意识到它们主要用作对变量的引用、哈希表中的键,甚至用作在方法中发送块的一种方式。

我的问题是,当我在方法中使用它们时,:+ :- :* 等符号到底是什么?

例如使用 :+ 对数组中的所有值求和:

puts [1,2,3].reduce(:+) 
 => 6

与以下结果相同:

puts [1,2,3].reduce {|sum, i| sum += i}
=> 6

如果我创建自己的 :+

版本
a = lambda {|sum,i| sum += i}
puts [1,2,3].reduce(&a)
=> 6

因此,我的第一个想法是 :+ 引用 {|sum, i| sum += i} 作为一个显式块,但我很难找到信息来证实这一点。

您传递给 reduce 的符号将被解释为调用每个元素的方法的名称。所以这个

collection.reduce(:foo)

相当于这个

collection.reduce { |memo, element| memo.foo(element) }

它与求和一起工作的原因是 + 运算符实际上只是一种数字方法。

 1.+(3) # => 4

My first thought is therefore that :+ references {|sum, i| sum += i} as an explicit block

不确定你的意思,但是 :+ 肯定没有引用这个块。或任何块。或任何东西。

符号只是名称。他们没有指向任何东西。决定它们的含义取决于使用它们的代码。

符号不是对变量的引用、哈希表中的键,也不是您声称的发送块的方式。事实是,符号是用来描述这些东西的,正如编写使用它们的相应方法的人所设计的那样,符号到这些东西的实际映射是在相应的方法中完成的。

对于您的特定示例,:+ 未引用 {|sum, i| sum += i} 或任何其他块; reduce 的替代语法的一个特点是允许传递一个符号,并将该符号转换为一个块。对应的块,虽然很接近,但不是你想的那样,而是:{|sum, i| sum + i}.