案例对象扩展特征的行为差异

Som*_*yya 1 scala

当我遇到Case1片段时,我正在寻找github上的scala项目来学习scala .特征扩展了Scala Product特征,然后案例对象扩展了该特征.编译得很好.为了更好地理解这一点我尝试了Case2似乎没有编译,它要求我absMethod()在case对象中定义.我不明白为什么在第一种情况下不会发生这种情况.

//Case 1
sealed abstract trait test1 extends Product with Serializable
case object test11 extends test1
test11.productArity  

//Case 2  
trait abstact extends Any{
  def absMethod():Int
}  
sealed abstract trait test2 extends abstact
case object test22 extends test2
test22.absMethod()
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 5

第一种情况是编译的,因为编译器productArity对案例类/对象有特殊的了解.作为编译过程的一部分,它不仅会创造一个同伴对象(case类),而且也可以实现多种方法,例如equals,hashCode,productArity(及以上).

如果您在typer阶段(scalac -Xprint:typer)之后查看第一个测试的输出:

sealed abstract trait test1 extends AnyRef with Product with Serializable;
  case object test11 extends AnyRef with com.github.yuvalitzchakov.TupleTest.test1 with Product with Serializable {
    def <init>(): com.github.yuvalitzchakov.TupleTest.test11.type = {
      test11.super.<init>();
      ()
    };
    override <synthetic> def productPrefix: String = "test11";
    <synthetic> def productArity: Int = 0;
    <synthetic> def productElement(x$1: Int): Any = x$1 match {
      case _ => throw new IndexOutOfBoundsException(x$1.toString())
    };
    override <synthetic> def productIterator: Iterator[Any] = scala.runtime.ScalaRunTime.typedProductIterator[Any](test11.this);
    <synthetic> def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[com.github.yuvalitzchakov.TupleTest.test11.type]();
    override <synthetic> def hashCode(): Int = -877171150;
    override <synthetic> def toString(): String = "test11";
    <synthetic> private def readResolve(): Object = com.github.yuvalitzchakov.TupleTest.test11
}
Run Code Online (Sandbox Code Playgroud)

您可以看到编译器如何实现productArity和分配0(因为一个对象没有构造函数参数),这是抽象的Product.对于自定义定义的抽象方法,您必须自己填充它,因此编译器在找不到实现时会抱怨.