【发布时间】:2015-09-26 18:39:43
【问题描述】:
在回答 this question 时,我偶然发现了一种我无法解释的行为。
来自:
val builder = new StringBuilder("foo bar baz ")
(0 until 4) foreach { builder.append("!") }
builder.toString -> res1: String = foo bar baz !
问题似乎很清楚,提供给 foreach 的函数缺少 Int 参数,因此StringBuilder.apply 被执行。但这并不能真正解释为什么它会附加“!”只有一次。所以我开始尝试..
我原以为以下六个语句是等价的,但结果字符串不同:
(0 until 4) foreach { builder.append("!") } -> res1: String = foo bar baz !
(0 until 4) foreach { builder.append("!")(_) } -> res1: String = foo bar baz !!!!
(0 until 4) foreach { i => builder.append("!")(i) } -> res1: String = foo bar baz !!!!
(0 until 4) foreach { builder.append("!").apply } -> res1: String = foo bar baz !
(0 until 4) foreach { builder.append("!").apply(_) } -> res1: String = foo bar baz !!!!
(0 until 4) foreach { i => builder.append("!").apply(i) } -> res1: String = foo bar baz !!!!
所以这些陈述显然是不等价的。有人能解释一下区别吗?
【问题讨论】:
-
a.b.c(_)是x => a.b.c(x)的糖(通过 SLS 6.23.1)。a.b.c _是val tmp = a.b; tmp.c _的糖(由 SLS 6.26.5 提供)。在前一种情况下,a.b会被一遍又一遍地评估,而在后一种情况下只会被评估一次。