Case class 扩展另一个 class 会丢失它的 toString?

Case class extending another class loses its toString?

class Bar { override def toString() = "Bar" }
case class Foo(s: String) extends Bar
Foo("bar") // "Bar"

为什么 Foo 无法生成 toString?这是一个错误还是实际上有一个原因?有什么方法可以 "get it back" (在某处是否有适用于案例 类 的默认实现)?

这不是错误,它是案例 class 从父级获取实现而不是生成它自己的实现的指定行为。

Scala Specification §5.3.2中提到:

Every case class implicitly overrides some method definitions of class scala.AnyRef unless a definition of the same method is already given in the case class itself or a concrete definition of the same method is given in some base class of the case class different from AnyRef. In particular:

  • Method toString: String returns a string representation which contains the name of the class and its elements.

我认为完成这项工作的唯一方法是您自己在 Foo 中再次显式覆盖 toString

要重现默认实现,您可以使用

override def toString() = productPrefix + productIterator.mkString("(", ", ", ")")

我好像记得这个方法在标准库的某个地方,但是现在找不到了。当然,这比手动实施效率低,例如productPrefix + "(" + field1 + ", " + ...,但这种方法在大多数情况下不会成为热点,而且出错的机会较少。