Какие методы генерируются для кейс-классов Scala?

Какие методы генерируются для кейс-классов Scala?

Я знаю, что некоторые методы генерируются специально для case-классов:

  • равняется
  • canEqual

Какие другие?

Кроме того, я вижу, что могу вызывать productArity() в любом классе дел. Как это работает? Другими словами, почему следующий код действителен?

case class CaseClass()

object CaseClass {
  val cc = new CaseClass()
  cc.productArity
}

4 ответа

Решение

Хороший способ создания методов для определенного класса в Scala - это использование javap команда.

Найдите файл.class, который был скомпилирован scalac а затем запустить javap -private Команда на это из вашего соответствующего инструмента командной строки. Это покажет вам конструкторы, поля и все методы для класса.

Вы можете сделать это для своего кейс-класса, чтобы увидеть, какие вещи автоматически предоставляются Scala.

Тематические классы смешиваются Product черта, которая обеспечивает productArity метод. Для тематических классов productArity Метод возвращает счетчик списка параметров, предоставленного в определении класса.

Учитывая Test.scala -

case class Test()

Вы можете запустить scalac Test.scala -print чтобы точно увидеть, что генерируется

[[syntax trees at end of                   cleanup]] // Test.scala
package com {
  case class Test extends Object with Product with Serializable {
    <synthetic> def copy(): com.Test = new com.Test();
    override <synthetic> def productPrefix(): String = "Test";
    <synthetic> def productArity(): Int = 0;
    <synthetic> def productElement(x$1: Int): Object = {
      case <synthetic> val x1: Int = x$1;
      case4(){
        matchEnd3(throw new IndexOutOfBoundsException(scala.Int.box(x$1).toString()))
      };
      matchEnd3(x: Object){
        x
      }
    };
    override <synthetic> def productIterator(): Iterator = runtime.this.ScalaRunTime.typedProductIterator(Test.this);
    <synthetic> def canEqual(x$1: Object): Boolean = x$1.$isInstanceOf[com.Test]();
    override <synthetic> def hashCode(): Int = ScalaRunTime.this._hashCode(Test.this);
    override <synthetic> def toString(): String = ScalaRunTime.this._toString(Test.this);
    override <synthetic> def equals(x$1: Object): Boolean = {
  case <synthetic> val x1: Object = x$1;
  case5(){
    if (x1.$isInstanceOf[com.Test]())
      matchEnd4(true)
    else
      case6()
  };
  case6(){
    matchEnd4(false)
  };
  matchEnd4(x: Boolean){
    x
  }
}.&&(x$1.$asInstanceOf[com.Test]().canEqual(Test.this));
    def <init>(): com.Test = {
      Test.super.<init>();
      scala.Product$class./*Product$class*/$init$(Test.this);
      ()
    }
  };
  <synthetic> object Test extends scala.runtime.AbstractFunction0 with Serializable {
    final override <synthetic> def toString(): String = "Test";
    case <synthetic> def apply(): com.Test = new com.Test();
    case <synthetic> def unapply(x$0: com.Test): Boolean = if (x$0.==(null))
      false
    else
      true;
    <synthetic> private def readResolve(): Object = com.this.Test;
    case <synthetic> <bridge> <artifact> def apply(): Object = Test.this.apply();
    def <init>(): com.Test.type = {
      Test.super.<init>();
      ()
    }
  }
}

Это правда, что дело класс автоматически определяет equals а также canEqual методы, но это также определить getter методы для аргументов конструктора. Там также есть toString метод, который вы можете вызвать.

Класс case также является экземпляром Product и, таким образом, наследовать эти методы. Вот почему вы называете productArity.

Класс case является просто неизменным, который вы создали. Если вы создаете объектный класс в том же файле с тем же именем, то это его сопутствующий объект.

Компаньон особенный, потому что он может получить доступ к элементам класса case, которые в противном случае являются частными.

Определение сопутствующего объекта автоматически создает apply метод.

Так что вы можете пойти CaseClass() в коде, вызывая конструктор без использования нового ключевого слова.

Ваша реализация не кажется правильной, вам может потребоваться больше чтения: http://daily-scala.blogspot.co.uk/2009/09/companion-object.html

Другие вопросы по тегам