的case改性剂引起Scala编译器自动生成的类共同样板代码。手动执行此代码很繁琐,而且会导致错误。以下案例类定义:
case class Person(name: String, age: Int)
...将自动生成以下代码:
class Person(val name: String, val age: Int) extends Product with Serializable { def copy(name: String = this.name, age: Int = this.age): Person = new Person(name, age) def productArity: Int = 2 def productElement(i: Int): Any = i match { case 0 => name case 1 => age case _ => throw new IndexOutOfBoundsException(i.toString) } def productIterator: Iterator[Any] = scala.runtime.ScalaRunTime.typedProductIterator(this) def productPrefix: String = "Person" def canEqual(obj: Any): Boolean = obj.isInstanceOf[Person] override def hashCode(): Int = scala.runtime.ScalaRunTime._hashCode(this) override def equals(obj: Any): Boolean = this.eq(obj) || obj match { case that: Person =>this.name==that.name&&this.age== that.age case _ => false } override def toString: String = scala.runtime.ScalaRunTime._toString(this) }
所述case改性剂还产生一个同伴对象:
object Person extends AbstractFunction2[String, Int, Person] with Serializable { def apply(name: String, age: Int): Person = new Person(name, age) def unapply(p: Person): Option[(String, Int)] = if(p == null) None else Some((p.name, p.age)) }
应用于时object,case修饰符具有相似的效果(尽管不那么引人注目)。这里的主要收益是toString实现和在hashCode各个过程中保持一致的值。请注意,案例对象(正确)使用引用相等:
object Foo extends Product with Serializable { def productArity: Int = 0 def productIterator: Iterator[Any] = scala.runtime.ScalaRunTime.typedProductIterator(this) def productElement(i: Int): Any = throw new IndexOutOfBoundsException(i.toString) def productPrefix: String = "Foo" def canEqual(obj: Any): Boolean = obj.isInstanceOf[this.type] override def hashCode(): Int = 70822 // "Foo".hashCode() override def toString: String = "Foo" }
仍然可以手动实现方法,否则该方法将由case类本身及其伴随对象中的修饰符提供。