gpt4 book ai didi

scala - 使用 scala Array.fill 中的 NPE

转载 作者:行者123 更新时间:2023-12-03 00:13:56 25 4
gpt4 key购买 nike

我正在阅读 Lex Spoon 所著的 Scala 编程,第三版(第四版中也有);比尔·维纳斯; Martin Odersky,并一路尝试示例。

以下示例来自本书 | Run in ScalaFiddle

abstract class Element {
def contents: Array[String]
val height = contents.length
val width = if (height == 0) 0 else contents(0).length
}

class UniformElement(
ch: Char,
override val width: Int,
override val height: Int
) extends Element {
private val line = ch.toString * width
def contents = Array.fill(height)(line)
}

val e: Element = new UniformElement('x', 2, 3)

在 REPL 或 Eclipse 工作表中尝试时,给出 java.lang.NullPointerException

如果我改变

  private val line = ch.toString * width

  private def line = ch.toString * width

没有发生错误。

谁能解释一下吗?

我使用的是 scala 2.11.8

最佳答案

这里的问题是,当您定义line时,构造函数中仍然没有定义contents。如果 line 是 val,它不会选择覆盖的 width,而是使用抽象宽度,而抽象宽度又使用 contents,它仍然是未定义,您将得到 NPE。您可以通过查看堆栈跟踪并注意到 NPE 是由抽象类中 width 的定义引发的来看到这一点。

line被定义为一个方法时,它不会执行,直到你调用它,那时内容将被完全定义,因为它可以调用line(另一个方法),这将被完全定义。

Run on ScalaFiddle

abstract class Element {
def contents: Array[String]
val height = contents.length
val width = if (height == 0) 0 else contents(0).length
}

class UniformElement(
ch: Char,
override val width: Int,
override val height: Int
) extends Element {
private def line: String = ch.toString * width
def contents = Array.fill(height)(line)
}

val e3: Element = new UniformElement('x', 2, 3)

底线:内容之间有一种“循环依赖”。

关于scala - 使用 scala Array.fill 中的 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42312232/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com