Scala:定义案例类构造函数时“覆盖受保护的val”导致错误

Posted

技术标签:

【中文标题】Scala:定义案例类构造函数时“覆盖受保护的val”导致错误【英文标题】:Scala: "override protected val" results in error when defining case class constructor 【发布时间】:2014-01-27 23:43:54 【问题描述】:

我遇到了一些与案例类和override protected val 相关的奇怪事情。

假设trait T 有一个受保护的def(或val)。

trait T 
  protected def s: String
  def print(): Unit = println(s)

我可以用val s 覆盖这个方法def s。没问题。

class A(override val s: String) extends T

好的。它编译。但这会使s 公开,因为没有受保护的关键字。

class B extends T 
  override protected val s: String = "Show me the money"

好的。它编译。 (class Bs 受到保护)

class C(override protected val s: String) extends T

好的。它编译。 (class Cs 受保护) 让我们用case class 来做这些。

case class D(override val s: String) extends T

好的。它编译。 (虽然class Ds 是公开的)

case class E() extends T 
  override protected val s: String = "Show me the money"

好的。它编译。 (class Es 受到保护)

case class F(protected val s: String) extends T

好的。它编译。 (class Fs 受到保护,并且s 也被覆盖,因为它在trait T 中并不具体。它是抽象的,所以override 关键字不是必需的。)

case class G(override protected val s: String) extends T

这里出现编译错误。 error: value s$1 overrides nothing

基本上,class Fclass G 是相同的。 class F 覆盖 s 并且 s 受到保护。这可以通过F("Something").print() 确实会打印Something 来证明。 override protected val 可用于案例类,如 class E 所示。定义普通类C没有出错。

但是,仅定义 class G 会导致编译错误。

为什么会这样?

我使用的是 Scala 2.10.3

【问题讨论】:

似乎是一个错误。请举报here。 @sschaef 好的。我会报告的。 绝对是一个错误。因为s 是受保护的,所以scala 会生成一个单独的合成<caseaccessor> def s$1 公共方法,该方法返回s,以便G 的伴随对象可以访问它,例如。两者都被标记为override,即使s$1 没有覆盖任何内容。 此外,案例类的受保护 val 参数实际上并没有任何用处:您可以使用提取器获取 val 的值,而无需成为子类。所以s 也可以公开。 提交:issues.scala-lang.org/browse/SI-8132 【参考方案1】:

此错误将在Scala 2.11.0-M8 中修复

https://issues.scala-lang.org/browse/SI-8132

【讨论】:

以上是关于Scala:定义案例类构造函数时“覆盖受保护的val”导致错误的主要内容,如果未能解决你的问题,请参考以下文章

Scala案例类私有构造函数但公共应用方法

scala入门教程:scala中的面向对象定义类,构造函数,继承

为啥私有构造函数在案例类中仍然可见?

Scala:是否可以使用宏注释来注释类的构造函数字段? (宏观天堂)

Scala基础:类和对象访问修饰符和构造器

Scala-构造函数