我发现Ruby中的这段代码非常有趣
(1..4).inject(&:+)
好的,我知道inject
做了什么,我知道这段代码基本上等同于
(1..4).inject(0) {|a,n| a + n}
但它究竟是如何运作的?
为什么&:+
与编写块{|a,n| a + n}
相同?
为什么它不需要初始值?我很好,正常值为0,但(1..4).inject(&:*)
也有效,初始值必须为1 ......
答案 0 :(得分:14)
如果您指定一个符号,那么集合中的每个元素都将传递给命名的备忘录方法
因此,指定符号相当于传递以下块:
{|memo, a| memo.send(sym, a)}
如果没有为memo显式指定初始值,则使用collection的第一个元素作为memo的初始值。
所以,没有魔法,Ruby只是将第一个元素作为初始值并开始从第二个元素注入。您可以通过编写[].inject(:+)
来检查它:它返回nil
而不是返回0的[].inject(0, :+)
。
编辑:我没注意到&符号。您不需要它,inject
将使用符号。但是如果你写它,符号就转换为块,它对other methods