覆盖Scala类型的toString方法

7

我有一个Scala的类型:

  type Fingerprint = Seq[(Int, Int)]

我想重写此类型的toString方法,如何实现?

3
我认为这里你并没有一个类型,而是有一个别名。因此,你无法覆盖任何东西,因为你没有声明一个类型。如果你从类型继承 => 那么你就可以进行覆盖。 - Alexey Raga
2
你并没有在这里创建一个类型。你只是为类型创建了一个别名。阅读此内容以澄清 - http://stackoverflow.com/questions/21306233/overriding-types-using-type-keyword-and-path-dependant-types/21306691#21306691 - serejja
2个回答

8

使用基于类型类的方法来解决这种问题有很好的理由,而不是使用Scala的toString(这可以说只是从Java遗留下来的一种不愉快的技术),而无法在任意类型上添加toString正是其中之一。例如,您可以使用ScalazShow类型类编写以下内容:

import scalaz._, syntax.show._

implicit val fingerprintShow: Show[Fingerprint] = Show.shows(
  _.map(p => p._1 + " " + p._2).mkString("\n")
)

然后:

scala> Seq((1, 2), (3, 4), (5, 6)).shows
res0: String = 
1 2
3 4
5 6

相比于基于隐式类或其他隐式转换的方法,更倾向于基于类型类的方法——因为通常情况下,类型类实例更易于推理和调试。


2
Scalaz很棒,但为了打印添加一个庞大的库有点过头了。 - flavian
@flavian:同意,自己编写 Show 很容易 - 我只是使用 Scalaz 的作为一个简单的例子。 - Travis Brown

5

覆盖toString可能不是最佳选择,但这里有一个简单的替代方案:

implicit class SeqAug[T <: (_, _)](val seq: Seq[T]) {
   def showInfo: String = {
      seq.map(p => p._1 + " " + p._2).mkString("\n") // or whatever you want.
   }
}
val x = Seq(("test" -> 5))
Console.println(x.showInfo)

您甚至可以限制增强的边界:

type Fingerprint = Seq[(Int, Int)]
implicit class SeqAug(val fingerprint: Fingerprint) {
  // same thing
}

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