昨天突然对于 inject 有了一些全新的体会。特记录下来,分享。
有关 inject, 之前的想法,一直将其作为一个累加器的替代. 其实,inject 的适用范围远远超出之前对于所谓`注入'的理解。
之前看 Ruby 代码风格的有关文章里面,都建议适用 inject, 应该以下方式:
inject(init) {|a, e| ... } # a表示accumulator, e表示element.
现在想想,这虽然没错,但是这会让人的对于 inject 的理解限制在 a 作为累加器的用途。
事实上,inject 应该这样理解:
将初始化值 init 作为代码块形参传入 a, 经过代码块处理后,并将处理结果重新赋值给 a
很显然,这个 a 并不仅仅扮演了累加器的角色。
甚至可以这样说:inject 更显著的意义在于:
可以完全取代以下方式的代码:
# 以下方式的代码, 应该总是使用inject代替
tmp = 0 # => 这是一个临时变量.
enum.each {|e| tmp = ... }
# 应该写为:
inject(0) {|tmp, e| tmp = ... } # => 很明显, 代码块内可以是任何内容. 不仅限于累加.
正如你看到的,更改为 inject 之后,更符合重构的基本定律。(减少了临时变量对外暴露)