2015-07-13 4 views
1

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

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

  • равен
  • canEqual

Что остальные?

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

case class CaseClass() 

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

ответ

4

Хороший способ, какие методы генерируются для определенного класса в Scala заключается в использовании команды javap.

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

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

Класс случая mixin Product признак, который обеспечивает метод productArity. Для классов case метод productArity вернет счет списка параметров, указанный в определении класса.

+0

Я побежал javap на код, предоставленный и я мог видеть, что она породила некоторые методы. Там были реализованы все методы продукта. Однако существовал метод productElements(), который возвращал итератору объектов, из которого я не получал, откуда он пришел. productElements не входит в Продукт. Этот метод объявлен где угодно? –

+0

Не могли бы вы скопировать и вставить подпись метода? – nattyddubbs

+0

public scala.collection.Iterator productElements(); –

1

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

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

0

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

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

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

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

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

1

Показано Испытание.Скала -

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>(); 
    () 
    } 
    } 
} 
+0

Отличный ответ Какую версию скаляса вы использовали? Он не генерировал productElements, который устарел с 2.8.0 –

+0

Я использую версию 2.11.5 – Maxim