此Scala代码在Scala 2.13下编译
val res = new scala.collection.mutable.StringBuilder
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( res += c )
}
}
如果看到foreach
方法缺少匿名函数的参数。执行时,它会为StringIndexOutOfBoundsException
给出一个异常res += c
,这令人困惑,因为StringBuilder
应该总是可附加的。
以下代码运行正常,没有例外。唯一的变化是将_
添加为foreach
参数函数的占位符:
val res = new scala.collection.mutable.StringBuilder()
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( _ => res += c )
}
}
答案 0 :(得分:5)
更确切地说,您的问题的答案位于String.apply()
或StringBuilder.apply()
中。
您看到,foreach
需要一个功能。用更准确的话来说就是一个计算为函数的表达式。
因此,它将首先对表达式求值以获取函数,然后将其应用于0 until 10
因此,当您考虑外部foreach
的第一次迭代时,您有c = 'h'
及其后继者,
(0 until 10).foreach(res += c )
在这里,res += c
将res
附加到其后将返回h
。
所以...求值函数是res
或res.apply
和res = "h"
。因此,以上实际上是
(0 until 10).foreach("h".apply)
因此,res.apply(0)
进行得很好...但是res.apply(1)
失败,出现StringIndexOutOfBoundsException
。
答案 1 :(得分:-3)
请参阅
的签名def foreach[U](f: A => U): Unit = {
}
(f: A => U) this is a function, not an expression.