为Scala案例类生成了哪些方法?为Scala案例类生成了哪些方法?
我知道,有些方法对case类专门生成:
- 等于
- canEqual
什么人?
此外,我看到我可以在任何case类上调用productArity()。这个怎么用?换句话说,为什么下面的代码是有效的?
case class CaseClass()
object CaseClass {
val cc = new CaseClass()
cc.productArity
}
为Scala案例类生成了哪些方法?为Scala案例类生成了哪些方法?
我知道,有些方法对case类专门生成:
什么人?
此外,我看到我可以在任何case类上调用productArity()。这个怎么用?换句话说,为什么下面的代码是有效的?
case class CaseClass()
object CaseClass {
val cc = new CaseClass()
cc.productArity
}
在斯卡拉特定类产生什么样的方法是使用javap
命令的一个好方法。
查找由scalac
编译的.class文件,然后在其各自的命令行工具上运行javap -private
命令。这将向您展示一个类的构造函数,字段和所有方法。
您可以为您的案例类做到这一点,看看Scala自动提供什么样的东西。
案例类别混入Product
特征,该特征提供productArity
方法。对于案例分类,productArity
方法将返回类定义中提供的参数列表的计数。
一个情况下CLASSE自动定义equals
和canEqual
方法,但它也定义getter
方法构造函数的参数这是真的。您还可以调用toString
方法。
案例类也是Product
的一个实例,因此继承了这些方法。这就是您称为productArity的原因。
案例类只是你创建的不可变的。 如果您在同一个文件中创建一个具有相同名称的对象类,那就是它的伴侣对象。
伴侣是特殊的,因为它可以访问否则为私人的案例类的元素。
定义伴随对象会自动创建一个apply
方法。
因此,您可以在代码中使用CaseClass()
,调用构造函数而不使用new关键字。
你的实现似乎并不正确,则可能需要更多阅读: http://daily-scala.blogspot.co.uk/2009/09/companion-object.html
鉴于测试。斯卡拉 -
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>();
()
}
}
}
这是一个很好的答案 你使用什么版本的scalac?它没有生成productElements,因为2.8.0 –
已弃用,所以我使用版本2.11.5 – Maxim
我跑的javap所提供的代码,我可以看到,它产生的一些方法。所有的产品方法都在那里实施。但是,有方法productElements()返回对象的迭代器,我没有得到它的来源。 productElements不在Product中。这个方法是在哪里声明的? –
你能复制和粘贴方法签名吗? – nattyddubbs
public scala.collection.Iterator productElements(); –