我想自定义案例类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()
位于何处?
答案 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:强>
您并非真的需要从产品扩展,但它可以让您访问案例类的许多功能,例如 productIterator 。