Scala Case 类 - 它们只是结构吗?

Scala Case Classes - Are they just structs?

所以我刚刚了解了 scala case 类,我被告知它们用于为一堆属性提供一个简单的包装器,以便更容易地测试是否相等。但是现在我有两个问题:

首先请注意,C++ 中的 struct 和 C# 中的 struct 是非常不同的东西。

  • C++ 中的结构就像常规的 类 但默认情况下,它们的成员 是 public。有关此主题的更多信息,请参阅 this post

  • C# 中的结构是值类型。当作为参数传递时,它们是 复制而不是通过指针传递。此行为类似于 Java 中的原始类型。这种行为是 C++ 中的默认行为,任何 classstruct.

你的第二个问题已经在 Eric 的回答中得到了回答,但重要的一点是 C# 结构完全按值传递(它们的所有字段都被复制),而 Java/C# 类 通过指针(按值传递)。如果您需要完整的解释,请参阅 this famous post

不幸的是,目前在 JVM 字节码中不可能有真正的值类型。您不能制作自己的类型,每次通过它时都会被完全复制。答案是否定的,case 类 不是像 C# 结构这样的值类型。 JVM 语言可能会尝试复制值类型的行为,但它将由 GC 管理并通过指针传递(按值传递)。

给出更直接的答案,否:

Case classes are like regular classes with a few key differences.

this page 上了解更多关于它们的信息。

不是真的。 scala case classes 最像的是... scala classes。

它们实际上 常规 scala classes 和一些额外的方法,这些方法会自动添加到它们中 - 即 .copy 在 class 本身以及伴生对象上的 .apply.unapply。他们还获得了一个很好的 .toString 方法,列出了所有字段,并且 .equals 比较了实例成员而不是对象引用。

在大多数其他方面,它们只是普通的 scala classes。

Scala classes 就像 Java classes。他们的 reference 是按值传递的。

Scala case classes 就像 scala classes 一样,但有些东西是自动为你生成的:

  • 构造函数的字段是可公开访问的(尽管 case class 默认情况下是不可变的,因此您可以将它们视为 Java 中的 public final 值,除非您声明案例字段 class 为 var)
  • 基于构造函数字段的equalshashCode方法
  • 伴随对象中的 applyunapply 方法
  • 显示构造函数所有值的toString方法
  • 一个copy方法

这是一个例子:

case class MasterOfTheUniverse(name: String, power: Int)

scala> MasterOfTheUniverse("He-Man", 100).name
res1: String = He-Man

scala> MasterOfTheUniverse("He-Man", 100).power
res2: Int = 100

scala> MasterOfTheUniverse("He-Man", 100).toString
res3: String = MasterOfTheUniverse(He-Man,100)

scala> MasterOfTheUniverse("He-Man", 100) == MasterOfTheUniverse("She-Ra", 90)
res4: Boolean = false

scala> MasterOfTheUniverse("She-Ra", 90) == MasterOfTheUniverse("She-Ra", 90)
res6: Boolean = true

scala> MasterOfTheUniverse("He-Man", 100).copy(name = "He-Manatee")
res7: MasterOfTheUniverse = MasterOfTheUniverse(He-Manatee,100)