【问题标题】:== for case class and "non-case" class in Scala== 用于 Scala 中的案例类和“非案例”类
【发布时间】:2015-01-30 02:54:18
【问题描述】:

我正在学习 Scala,遇到了以下难题。

我可以定义以下案例类:

abstract class Expr
case class Number(n: Int) extends Expr

当我从 Number 类创建两个实例并比较它们时

val x1 = Number(1)
val x2 = Number(1)
x1 == x2

我有以下结果:

x1: 数 = 数(1)

x2: 数 = 数(1)

res0: Boolean = true

所以x1x2 是一样的。

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

abstract class Expr
class Number(n: Int) extends Expr

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

val x1 = new Number(1)
val x2 = new Number(1)
x1 == x2

我有以下输出:

x1: Number = Number@1175e2db

x2:数字 = 数字@61064425

res0: Boolean = false

说这次x1x2不一样了。

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

谢谢, 平移

【问题讨论】:

  • 对不起,我错误地创建了val x2 = Number(2),它应该是val x2 = Number(1)。我已经更正了。

标签: scala case-class


【解决方案1】:

当您在 Scala 中定义案例类时,编译器会生成一个 equals 方法来检查深度相等(即类的内容)。

发件人:http://www.scala-lang.org/old/node/107

Scala 编译器为每个 case 类生成实现结构相等的 equals 方法和一个 toString 方法。

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

关于浅层和深层相等的区别,请参见:
What is the difference between being shallowly and deeply equal? How is this applied to caching?

【讨论】:

  • 为了精确起见,调用== 不会强制进行引用相等检查,它实际上会调用equals 方法,您可以覆盖该方法来做任何您想做的事情。引用相等只是普通类的默认实现,强制引用相等检查可以通过eq 方法完成。 == 的这种行为与 Java 中的行为不同。
  • 通常使用“浅”和“深”这两个词的含义与此答案不同。普通类不会覆盖equals(),默认实现是“引用”相等,即比较对象本身的引用。案例类比较它们的字段是否相等,但它们将比较委托给字段的 equals() 方法,如果以相同的方式定义,则导致深度相等,但如果不是,则导致浅相等(只有 1 级深度)。 en.wikipedia.org/wiki/Object_copying#Shallow_copy
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
相关资源
最近更新 更多