为Scala案例类生成了哪些方法?

为Scala案例类生成了哪些方法?,scala,case-class,Scala,Case Class,为Scala案例类生成了哪些方法 我知道有些方法是专门为案例类生成的: 相等于 卡内夸尔 其他的是什么 另外,我发现我可以对任何case类调用productArity()。这是怎么回事?换句话说,为什么下面的代码是有效的 case class CaseClass() object CaseClass { val cc = new CaseClass() cc.productArity } 一个case类确实会自动定义equals和canEqual方法,但它也会为构造函数参数定义g

为Scala案例类生成了哪些方法

我知道有些方法是专门为案例类生成的:

  • 相等于
  • 卡内夸尔
其他的是什么

另外,我发现我可以对任何case类调用productArity()。这是怎么回事?换句话说,为什么下面的代码是有效的

case class CaseClass()

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

一个case类确实会自动定义
equals
canEqual
方法,但它也会为构造函数参数定义
getter
方法。还有一个
toString
方法可以调用


case类也是
Product
的实例,因此继承这些方法。这就是为什么要调用productArity。

在Scala中为特定类生成方法的一个好方法是使用
javap
命令

找到由
scalac
编译的.class文件,然后从相应的命令行工具对其运行
javap-private
命令。这将显示类的构造函数、字段和所有方法

您可以为您的case类执行此操作,以查看Scala自动提供了哪些类型的东西


案例类混合在
产品
特性中,该特性提供了
产品性
方法。对于案例类,
productArity
方法将返回类定义中提供的参数列表的计数。

给定测试。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>();
      ()
    }
  }
}
[[清理结束时的语法树]]///Test.scala
软件包组件{
案例类测试使用可序列化的产品扩展对象{
def copy():com.Test=new com.Test();
覆盖def productPrefix():String=“Test”;
def productArity():Int=0;
def productElement(x$1:Int):对象={
案例val x1:Int=x$1;
案例4(){
matchEnd3(抛出新的IndexOutOfBoundsException(scala.Int.box(x$1.toString()))
};
matchEnd3(x:对象){
x
}
};
重写def productIterator():Iterator=runtime.this.ScalaRunTime.typedProductIterator(Test.this);
def canEqual(x$1:Object):Boolean=x$1.$isInstanceOf[com.Test]();
重写def hashCode():Int=ScalaRunTime.this.\u hashCode(Test.this);
override def toString():String=ScalaRunTime.this.\u toString(Test.this);
覆盖定义等于(x$1:Object):布尔={
案例值x1:Object=x$1;
案例5(){
if(x1.$isInstanceOf[com.Test]())
matchEnd4(真)
其他的
案例6()
};
案例6(){
matchEnd4(假)
};
matchEnd4(x:布尔值){
x
}
}.和&(x$1$ASINSTANCOF[com.Test]().canEqual(Test.this));
def():com.Test={
测试。超级。();
scala.Product$class./*Product$class*/$init$(Test.this);
()
}
};
对象测试使用Serializable扩展了scala.runtime.AbstractFunction0{
最终覆盖def toString():String=“Test”;
case def apply():com.Test=new com.Test();
case def unapply(x$0:com.Test):Boolean=if(x$0.==(null))
假的
其他的
是的;
private def readResolve():Object=com.this.Test;
case def apply():Object=Test.this.apply();
def():com.Test.type={
测试。超级。();
()
}
}
}

我在提供的代码上运行了javap,我可以看到它生成了一些方法。所有的产品方法都在那里实现。然而,有一个方法productElements()返回了我没有得到的对象的迭代器。productElements不在产品中。此方法是否在任何地方声明?是否可以复制并粘贴方法签名?public scala.collection.Iterator productElements();所以使用scalac-print from answer,我得到的是:
@deprecated(“改用productIterator”,“2.8.0”)def productElements():Iterator=scala.Product$class.productElements(CaseClass.this)我们可以看到productElements已被弃用。这是一个很好的答案您使用了什么版本的scalac?它没有生成productElements,自2.8.0以来,productElements已被弃用