【发布时间】:2017-07-13 15:23:09
【问题描述】:
class Bar { override def toString() = "Bar" }
case class Foo(s: String) extends Bar
Foo("bar") // "Bar"
为什么Foo 没有得到它的toString 生成?这是一个错误还是真的有原因?有什么方法可以“取回”(是否有默认实现可能适用于案例类)?
【问题讨论】:
标签: scala case-class
class Bar { override def toString() = "Bar" }
case class Foo(s: String) extends Bar
Foo("bar") // "Bar"
为什么Foo 没有得到它的toString 生成?这是一个错误还是真的有原因?有什么方法可以“取回”(是否有默认实现可能适用于案例类)?
【问题讨论】:
标签: scala case-class
这不是一个错误,它是案例类从父级获取它的实现而不是生成它自己的一个的指定行为。
Scala Specification §5.3.2中提到过:
每个案例类都隐式地覆盖了类的一些方法定义
scala.AnyRef除非已经给出了相同方法的定义 在案例类本身或同一方法的具体定义中 在不同于 AnyRef 的案例类的某些基类中给出。 特别是:
- 方法
toString:字符串返回一个字符串表示,其中包含类的名称及其元素。
我认为完成这项工作的唯一方法是自己在Foo 中再次明确覆盖toString。
【讨论】:
toString ...问题是我要什么覆盖它?是否有一个函数可以调用以获得默认行为,还是我必须实际重复整个实现?
toString,尽管我认为这可能是一些编译器实现细节。
要重现默认实现,您可以使用
override def toString() = productPrefix + productIterator.mkString("(", ", ", ")")
我似乎记得这个方法在标准库的某个地方,但现在找不到。当然,这将比手动实施效率低,例如如productPrefix + "(" + field1 + ", " + ...,但这种方法在大多数情况下不会成为热点,并且出错的机会更少。
【讨论】:
toString 方法,该方法将再次成为默认方法或由您实现,并且哪个无关紧要(据我所知)。当然,如果你想像stackoverflow.com/questions/15718506/… 那样进行漂亮的打印,事情会变得更加复杂,但标准实现并没有做到这一点。
ScalaRuntime._toString(this),正如提到的here :)