我觉得这段 Ruby 代码相当有趣
(1..4).inject(&:+)
好的,我知道inject
的作用,我也知道这段代码基本上等同于
(1..4).inject(0) {|a,n| a + n}
但它到底是如何工作的?
为什么&:+
和写{|a,n| a + n}
块是相同的?
为什么它不需要一个初始值?我可以用0作为initial value,但是(1..4).inject(&:*)
也可以,而那里必须有一个初始值为1...
我觉得这段 Ruby 代码相当有趣
(1..4).inject(&:+)
好的,我知道inject
的作用,我也知道这段代码基本上等同于
(1..4).inject(0) {|a,n| a + n}
但它到底是如何工作的?
为什么&:+
和写{|a,n| a + n}
块是相同的?
为什么它不需要一个初始值?我可以用0作为initial value,但是(1..4).inject(&:*)
也可以,而那里必须有一个初始值为1...
来自Ruby文档:
如果您指定一个符号,那么集合中的每个元素都将传递给memo的指定方法
因此,指定符号等同于传递以下块:
{|memo, a| memo.send(sym, a)}
如果您没有明确为memo指定初始值,则使用集合的第一个元素作为memo的初始值。
因此,没有任何魔法,Ruby只是将第一个元素作为初始值,并从第二个元素开始注入。 您可以通过编写 [].inject(:+)
来检查它:它返回 nil
而不是 [].inject(0,:+)
,后者返回0。
编辑:我没有注意到&符号。您不需要它, inject
将使用符号。但是,如果您写了它,则该符号会转换为块,可以在其他方法中非常有用。