scala - 为什么此代码编译并在执行时给出运行时错误
问题描述
此 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 )
}
}
解决方案
您的问题的答案在于String.apply()
或StringBuilder.apply()
更准确地说。
你看,foreach
期望一个函数。更准确地说,计算结果为函数的表达式。
因此,它将首先评估表达式以获取函数,然后将该函数应用于0 until 10
因此,当您考虑 external 的第一次迭代时foreach
,您拥有c = 'h'
并遵循,
(0 until 10).foreach(res += c )
在这里,res += c
将res
在附加后返回h
。
所以...评估的函数是res
or res.apply
with res = "h"
。因此,上述实际上是,
(0 until 10).foreach("h".apply)
所以,res.apply(0)
进展顺利......但res.apply(1)
失败了StringIndexOutOfBoundsException
.
推荐阅读
- javascript - 使用 JSON 数组添加带有 appendChild 的嵌套元素
- ios - AR Kit 2.0 获取跟踪图像的图像细节?
- python - 如何检查两个列表是否与重复项相等?
- javascript - 查找通过在 linux 中无头运行 jasmine 触发的 Chromium 堆栈跟踪的原因
- java - NoSuchMethodError:com.fasterxml.jackson.core.JsonStreamContext
- swift - swift - 从类外的模型文件中激活类上的 segue?实例成员不能用于类型
- sql - Presto/SQL - 将字符串时间戳转换为日期会引发错误
- git - Git:如何在提交前将文件标记为已审核?
- conda - conda build 后如何获取 conda 包的路径
- q# - 如果 Q# 函数可以运行使用比特的经典代码,那么经典代码是否仍能以量子计算机运行的速度运行?