为什么这段代码编译并在执行时给出运行时错误
Why this code compiles and it gives runtime error when it executes
此 Scala 代码在 Scala 2.13 下编译
val res = new scala.collection.mutable.StringBuilder
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( res += c )
}
}
如果您看到 foreach
方法缺少匿名函数的参数。当它被执行时,它为 res += c
给出了一个异常 StringIndexOutOfBoundsException
这令人费解,因为 StringBuilder
应该总是可追加的。
以下代码运行良好,没有异常。唯一的变化是添加 _
作为 foreach
参数函数的占位符:
val res = new scala.collection.mutable.StringBuilder()
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( _ => res += c )
}
}
请看
的签名
def foreach[U](f: A => U): Unit = {
}
(f: A => U) this is a function, not an expression.
您的问题的答案在于 String.apply()
或 StringBuilder.apply()
更准确。
你看,foreach
需要一个函数。更准确地说,一个计算结果为函数的表达式。
因此,它将首先计算表达式以获得函数,然后它将应用该函数 0 until 10
因此,当您考虑外部 foreach
的第一次迭代时,您有 c = 'h'
和后续
(0 until 10).foreach(res += c )
在这里,res += c
将 return 添加 h
后 res
。
所以...评估的函数是 res
或 res.apply
和 res = "h"
。因此,以上实际上是,
(0 until 10).foreach("h".apply)
所以,res.apply(0)
进展顺利...但是 res.apply(1)
失败 StringIndexOutOfBoundsException
。
此 Scala 代码在 Scala 2.13 下编译
val res = new scala.collection.mutable.StringBuilder
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( res += c )
}
}
如果您看到 foreach
方法缺少匿名函数的参数。当它被执行时,它为 res += c
给出了一个异常 StringIndexOutOfBoundsException
这令人费解,因为 StringBuilder
应该总是可追加的。
以下代码运行良好,没有异常。唯一的变化是添加 _
作为 foreach
参数函数的占位符:
val res = new scala.collection.mutable.StringBuilder()
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( _ => res += c )
}
}
请看
的签名def foreach[U](f: A => U): Unit = {
}
(f: A => U) this is a function, not an expression.
您的问题的答案在于 String.apply()
或 StringBuilder.apply()
更准确。
你看,foreach
需要一个函数。更准确地说,一个计算结果为函数的表达式。
因此,它将首先计算表达式以获得函数,然后它将应用该函数 0 until 10
因此,当您考虑外部 foreach
的第一次迭代时,您有 c = 'h'
和后续
(0 until 10).foreach(res += c )
在这里,res += c
将 return 添加 h
后 res
。
所以...评估的函数是 res
或 res.apply
和 res = "h"
。因此,以上实际上是,
(0 until 10).foreach("h".apply)
所以,res.apply(0)
进展顺利...但是 res.apply(1)
失败 StringIndexOutOfBoundsException
。