scala - 为什么对对象的 val 的 scala 测试断言会抛出 NullPointerException?
问题描述
在测试 Scala 代码时,我在断言来自对象的值时遇到了一个奇怪的 NPE。
这是重现该问题的最少代码:
主/斯卡拉/Playground.scala:
object Playground extends App {
val greeting = "Hello Scala"
println(greeting)
}
测试/scala/PlaygroundSpec.scala:
import org.scalatest.wordspec._
class PlaygroundSpec extends AnyWordSpec {
"The playground code" should {
"say hello" in {
assert(Playground.greeting.contains("Hello")) // Throws NPE because greeting is null. How???
}
}
}
示例程序运行良好并打印“hello Scala”,但测试在断言行抛出 NullPointerException,因为greeting
is null
.
如果它greeting
是null
用字符串常量初始化的呢?
注意:添加
lazy
到val
声明中使其工作并且测试通过。
解决方案
你可以这样定义Playground
:
object Playground /*extends App*/ {
val greeting = "Hello Scala"
println(greeting)
}
或者你可以这样定义greeting
:
object Playground extends App {
lazy val greeting = "Hello Scala"
println(greeting)
}
Scala 2.x 的这种奇怪行为的解释是App
延迟加载的特性。这在过去对许多其他人来说一直是个问题。Scala 3 将改变这一点。
对于 Scala 2,最安全的选择是将对象引用移到 的主体之外App
,例如:
class Playground {
val greeting = "Hello Scala"
println(greeting)
}
object Playground extends App {
new Playground
}
推荐阅读
- python - Python Regex Bullet Point 和多行匹配
- hl7-fhir - HL7 FHIR 将资源标记为匿名
- .htaccess - 301 将 HTTP 重定向到 HTTPS - 非 www 到 www
- javascript - 反应儿童抛出 PropTypes 错误
- r - 在同一图中绘制 ecdf 和密度并放大到特定部分
- c# - ASP.NET Core 2.0 中的验证:语法与验证问题
- java - 如何使一个类中的更改在另一个类中生效?
- reason - 编译时出现错误“找不到变体构造函数”
- javascript - 无法解决IOS的mouseout
- java - 使用动态标签将 XML 反序列化为 POJO