如何避免Scala的case class默认toString函数被覆盖?

15

Scala的case class有一个默认的toString函数。但是当这个case class继承了一个已经存在toString()函数的trait时,它就会变得无用。如何避免这种情况?


这里有一个类似的问题:http://stackoverflow.com/questions/20998866/scala-prevent-mixing-methods - nitishagar
3个回答

28

好的,这是最简单的答案:

override def toString = ScalaRunTime._toString(this)

故事就这样结束了 :)


那是DRY且易于操作的。 - som-snytt
2
新手问题:由于多种原因,这给了我错误;我通过以下方式解决了这个问题:override def toString() = ScalaRunTime._toString(this)(我必须在 toString 后面添加括号)。此外,我必须明确让我的特定类 extend Product。有什么方法可以避免这种情况吗?(另外,我使用了 import scala.runtime.ScalaRunTime 来避免完全限定名称。) - not-just-yeti
3
声明为 case class 相当于继承 Product。其他部分与不同版本的 Scala 快捷方式有关,不重要。 - tribbloid

9

这里有一个解决办法,我认为可能有效,但可能过于复杂,你来决定吧。它涉及使用一个 trait

trait StandardToString { this:Product =>
  override def toString = productPrefix + productIterator.mkString("(", ",", ")")
}

现在我们来试着用一些样例进行操作:
trait Human {
   override def toString() = "Human"
}

case class European(firstName:String) extends Human

并使用特性运行它:

scala> new European("Falco") with StandardToString
res0: European with StandardToString = European(Falco)

当然,使用trait后,您将得到以下结果。
scala> new European("Adele")
res1: European = Human

1

更准确地说,案例类toString没有被生成,而不是被覆盖。

这并不是一个很好的答案或解决方法。

scala> trait X { override def toString = "X" }
defined trait X

scala> case class Y(i: Int) extends X
defined class Y

scala> Y(42)
res0: Y = X

scala> case class Y(i: Int)
defined class Y

scala> class Z(x: Int) extends Y(x) with X { override def toString = super[Y].toString }
defined class Z

scala> new Z(42)
res1: Z = Y(42)

你不能使用Trait来做到这一点:

scala> trait R extends Y { override def toString = super[Y].toString }
<console>:9: error: Implementation restriction: traits may not select fields or methods from super[C] where C is a class
       trait R extends Y { override def toString = super[Y].toString }
                                                   ^

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接