2015-07-13 31 views
1

爲Scala案例類生成了哪些方法?爲Scala案例類生成了哪些方法?

我知道,有些方法對case類專門生成:

  • 等於
  • canEqual

什麼人?

此外,我看到我可以在任何case類上調用productArity()。這個怎麼用?換句話說,爲什麼下面的代碼是有效的?

case class CaseClass() 

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

回答

4

在斯卡拉特定類產生什麼樣的方法是使用javap命令的一個好方法。

查找由scalac編譯的.class文件,然後在其各自的命令行工具上運行javap -private命令。這將向您展示一個類的構造函數,字段和所有方法。

您可以爲您的案例類做到這一點,看看Scala自動提供什麼樣的東西。

案例類別混入Product特徵,該特徵提供productArity方法。對於案例分類,productArity方法將返回類定義中提供的參數列表的計數。

+0

我跑的javap所提供的代碼,我可以看到,它產生的一些方法。所有的產品方法都在那裏實施。但是,有方法productElements()返回對象的迭代器,我沒有得到它的來源。 productElements不在Product中。這個方法是在哪裏聲明的? –

+0

你能複製和粘貼方法簽名嗎? – nattyddubbs

+0

public scala.collection.Iterator productElements(); –

1

一個情況下CLASSE自動定義equalscanEqual方法,但它也定義getter方法構造函數的參數這是真的。您還可以調用toString方法。

案例類也是Product的一個實例,因此繼承了這些方法。這就是您稱爲productArity的原因。

0

案例類只是你創建的不可變的。 如果您在同一個文件中創建一個具有相同名稱的對象類,那就是它的伴侶對象。

伴侶是特殊的,因爲它可以訪問否則爲私人的案例類的元素。

定義伴隨對象會自動創建一個apply方法。

因此,您可以在代碼中使用CaseClass(),調用構造函數而不使用new關鍵字。

你的實現似乎並不正確,則可能需要更多閱讀: 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

這是一個很好的答案 你使用什麼版本的scalac?它沒有生成productElements,因爲2.8.0 –

+0

已棄用,所以我使用版本2.11.5 – Maxim