val
Scala 自动创建一个与类中声明的任何方法(包括案例类的字段)同名的方法,以支持称为引用透明性的概念。这也是您可以用 a覆盖 adef
val
的原因。如果您仍然持怀疑态度,您可以像这样自己测试:
首先,创建一个包含单个案例类的 Scala 文件。
// MyCase.scala
case class MyCase(myField1: Int, myField2: String)
现在,用scalac
. 这应该导致两个类。对于上面的示例,我得到MyCase.class(代表实际案例类类型)和MyCase$.class(代表案例类的自动生成的伴随对象)。
$ scalac MyCase.scala
$ ls
MyCase$.class MyCase.class MyCase.scala
现在您可以检查与.class
您使用声明的案例类相对应的结果文件javap
。(javap
检查 Java 字节码的标准工具——它与javac
JDK 一起分发。)
$ javap -private MyCase
Compiled from "MyCase.scala"
public class MyCase extends java.lang.Object implements scala.Product,scala.Serializable{
private final int myField1;
private final java.lang.String myField2;
public static final scala.Function1 tupled();
public static final scala.Function1 curry();
public static final scala.Function1 curried();
public scala.collection.Iterator productIterator();
public scala.collection.Iterator productElements();
public int myField1();
public java.lang.String myField2();
public MyCase copy(int, java.lang.String);
public java.lang.String copy$default$2();
public int copy$default$1();
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public boolean canEqual(java.lang.Object);
private final boolean gd1$1(int, java.lang.String);
public MyCase(int, java.lang.String);
}
请注意生成的类如何同时具有与案例类的字段对应的aprivate final int myField1
和 a 。对于.public int myField1()
myField1
myField2
在 JVM 上,方法返回类型不是方法签名的一部分。这意味着如果两个方法具有相同的名称和相同的参数类型,那么它们被认为是冲突的方法声明。这意味着您不能def a: Array[Byte]
在示例中声明,因为val a: String
已经存在,也没有参数。
更新:
我只是查看了库代码,根据示例,案例类应该可以正常工作。README中有一条注释说解析案例类在 REPL 中不起作用。那会是你的问题吗?如果没有,您应该真正发布您遇到的错误。编辑:没关系,我在指向其他帖子的链接中看到了您所说的错误。如果我想到对该问题的回应,我会在那里发布。