生成的代码工件
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
值。请注意,case 对象(正确)使用引用相等:
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
修饰符在类本身及其伴随对象中提供的方法。