【问题标题】:What's behind Scala case classes?Scala 案例类的背后是什么?
【发布时间】:2013-11-03 19:13:20
【问题描述】:

我对 Scala 很陌生,但我已经使用过案例类。我了解了常规类和案例类之间的主要区别,总结为here

我什至不想摆脱案例类,但我想知道转换所需的代码是什么,例如:

class Tweet(val user: String, val text: String) {
  override def toString: String =
    "User: " + user + "\n" +
    "Text: " + text + "]"
}

进入一个完整的案例“兼容”类。我的意思是,我想编写一个案例类的相同“行为”,但不使用case 关键字。这是可能的还是编译器做了一些我无法通过代码得到的事情(不包括优化)?

再次澄清我在问什么,当我需要一个案例类时,我总是会使用 case 关键字,但我想知道 Scala 编译器(一般意义上)为我做了什么, 用代码表示。

编辑: 另一个疑问:编译器会以某种方式标记我的手工编码类与标准案例类,以便我可以观察到执行中的不同行为吗?

【问题讨论】:

  • Scala 编译器不区分这两者。案例类只是普通类,但编译器会自动生成很多与它们相关的东西,因此它们的行为不同。您可以考虑为您所面临的问题提供更简单的答案。

标签: scala


【解决方案1】:

您可以查看 scala 规范中的第 5.3.2 章“案例类”。

如果我总结正确,以下是自动生成的:

  • 为类元素生成访问器
  • 自动生成带有应用/取消应用的提取器对象
  • 自动添加方法副本
  • 方法 equals、hashCode、toString 被覆盖

您可以比较 scala 源代码和生成的 java 字节码来确定。

【讨论】:

  • 如果觉得您可以创建一个在技术上类似于案例类的常规类,但类型系统不会知道它是一个案例类,那么它可能仍然会导致使用差异(也许与模式匹配)。但我对 scala 的了解不足以确定这一点。
  • @giampaolo 您将问题更改为询问运行时,而 ewrnli 提到了类型系统,这是编译时的事情。我能想到的唯一区别是,如果您尝试用另一个案例类扩展一个案例类(过去是可能的,但它会导致问题),编译器会抱怨。如果您从其他地方导入它,它如何知道它所扩展的类是一个案例类,我不确定。
  • @LuigiPlinge:好的,我改变了最后一句话。我希望现在更清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多