2015-07-13 67 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