为元组/产品/案例类实现toString()

时间:2015-11-13 16:48:52

标签: scala tuples tostring

我想自定义案例类toString()方法。

case class MyCaseClass {
  // stuff ..
 override def toString() {
   // mostly same as default but I want to omit some of the fields
}

我的第一眼看到的是所有案例类扩展的产品和产品。但事实证明它们是不包含toString()的特征。

那么在案例类(/ Products)的scala库类层次结构中,toString()位于何处?

2 个答案:

答案 0 :(得分:3)

toString由scala编译器自动生成。您唯一可以自定义的是productPrefix

这是一个简单的案例类

case class Foo(a: Int, b: Int)

及其toString方法(使用:scala控制台中的javap -c Foo)

  public java.lang.String toString();
    Code:
       0: getstatic     #63                 // Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
       3: aload_0
       4: invokevirtual #85                 // Method scala/runtime/ScalaRunTime$._toString:(Lscala/Product;)Ljava/lang/String;
       7: areturn

正如您所看到的,toString是通过调用scala.runtime.ScalaRunTime._toString(this)实现的。

如果您只想更改班级名称,可以覆盖productPrefix:

case class FooImpl(a: Int, b: Int) {
  override def productPrefix = "Foo"
}

scala> FooImpl(1,2)
res1: FooImpl = Foo(1,2)

如果你想做一些更复杂的事情,比如省略一些字段,你将不得不重写toString

case class Foo3(a: Int, b: Int, c: Int) {
  override def toString = "Foo3" + (a, b)
}

scala> Foo3(1,2,3)
res2: Foo3 = Foo(1,2)

另一种选择是拥有多个参数列表。

scala> case class Foo3(a: Int, b: Int)(c: Int)
defined class Foo3

scala> Foo3(1,2)(3)
res3: Foo3 = Foo3(1,2) // only the arguments of the first argument list are printed

scala> Foo3(1,2)(3).productArity
res4: Int = 2 // product arity is number of arguments of the first argument list

答案 1 :(得分:1)

<强> CODE:

object CaseTest {

  trait TSV extends Product {  // #1
    override def toString:String = productIterator.mkString("\t")  // #2
  }

  case class A(name:String, age:Int) extends TSV // #3

  case class B(a:A, b:Boolean) extends TSV

  def main(args: Array[String]) {
    val a = A("Me", 23)
    val b = B(A("Other", 45), b = true)
    println(a)
    println(b)
  }  
}

<强>输出:

Me|23
Other|45|true

<强> PROCESS:

  1. 创建一个扩展产品
  2. 的特征
  3. 覆盖新特征
  4. 中的 toString 方法
  5. 从新的特征
  6. 扩展所有案例类

    您并非真的需要从产品扩展,但它可以让您访问案例类的许多功能,例如 productIterator