==用于案例类和Scala中的"非案例"类

pan*_*anc 4 scala case-class

我正在研究Scala并遇到了以下难题.

我可以定义以下案例类:

abstract class Expr
case class Number(n: Int) extends Expr
Run Code Online (Sandbox Code Playgroud)

当我从类中创建两个实例Number并进行比较时

val x1 = Number(1)
val x2 = Number(1)
x1 == x2
Run Code Online (Sandbox Code Playgroud)

我有以下结果:

x1:数字=数字(1)

x2:数字=数字(1)

res0:Boolean = true

所以,x1和x2是相同的.

但是,如果我case在Number类定义中删除修饰符,即

abstract class Expr
class Number(n: Int) extends Expr
Run Code Online (Sandbox Code Playgroud)

然后Number以相同的方式比较该类中的两个实例

val x1 = new Number(1)
val x2 = new Number(1)
x1 == x2
Run Code Online (Sandbox Code Playgroud)

我有以下输出:

x1:Number = Number @ 1175e2db

x2:Number = Number @ 61064425

res0:Boolean = false

它说这次x1和x2不同.

你能告诉我这是为什么吗?case在比较两个实例方面有什么区别?

谢谢,潘

xbo*_*nez 9

在Scala中定义case类时,编译器会生成一个equals检查深度相等的方法(即类的内容).

来自:http://www.scala-lang.org/old/node/107

对于每个案例类,Scala编译器都会生成实现结构相等性的equals方法和toString方法.

删除case关键字时,会生成常规类,并对==它们执行检查以获得引用(浅)相等性.由于您要比较类的两个唯一实例,因此即使它们的内容相同,它们也会失败引用相等性.

对于浅层和深层平等之间的区别,请参阅:浅层和深层
划分的区别是什么?这是如何应用于缓存的?

  • 为了精确起见,调用`==`不强制引用相等检查,它实际上会调用`equals`方法,你可以覆盖它来做你想做的任何事情.引用相等只是普通类的默认实现,强制引用相等性检查可以通过`eq`方法完成.例如,`==`的这种行为与Java不同. (2认同)