【问题标题】:Case class extending another class loses its toString?扩展另一个类的案例类丢失了它的toString?
【发布时间】: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


    【解决方案1】:

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

    Scala Specification §5.3.2中提到过:

    每个案例类都隐式地覆盖了类的一些方法定义 scala.AnyRef 除非已经给出了相同方法的定义 在案例类本身或同一方法的具体定义中 在不同于 AnyRef 的案例类的某些基类中给出。 特别是:

    • 方法toString:字符串返回一个字符串表示,其中包含类的名称及其元素。

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

    【讨论】:

    • 是的,我明白了,我必须覆盖toString ...问题是我要什么覆盖它?是否有一个函数可以调用以获得默认行为,还是我必须实际重复整个实现?
    • @Dima 您的意思是:“是否有 API 可以提供案例类并获取该类的字符串表示形式”?如果是这样,不确定,也许在任意案例类上查看反编译的toString,尽管我认为这可能是一些编译器实现细节。
    • @Dima 也许这会有所帮助:stackoverflow.com/questions/15718506/…
    【解决方案2】:

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

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

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

    【讨论】:

    • 它适用于嵌套结构吗?即案例类中的案例类?
    • 它将使用该案例类的toString 方法,该方法将再次成为默认方法或由您实现,并且哪个无关紧要(据我所知)。当然,如果你想像stackoverflow.com/questions/15718506/… 那样进行漂亮的打印,事情会变得更加复杂,但标准实现并没有做到这一点。
    • 我认为你试图记住的方法是ScalaRuntime._toString(this),正如提到的here :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多