Scala案例类 - 它们只是结构吗?

问题描述 投票:4回答:3

所以我刚刚学习了scala案例类,并且我被告知他们习惯于围绕一堆属性提供一个简单的包装器,以便更容易测试相等性。但现在我有两个问题:

  • 这与C ++ / C#中的结构是一回事吗?
  • 案例类是值类型还是引用类型?
scala struct case-class
3个回答
6
投票

首先,C ++中的struct和C#中的struct是非常不同的东西。所以要问Scala中的case类是否与那两个没有意义的东西相同。

  • C ++中的结构就像常规类一样,但默认情况下,它们的成员是公共的。有关此主题的更多信息,请参阅this post
  • C#中的结构是值类型。作为参数传递时,它们被复制而不是通过指针传递。此行为类似于Java中的基本类型。此行为是C ++中的默认行为,包含任何classstruct

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

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

为了给出更直接的答案,不要:

案例类就像常规类,但有一些关键差异。

this page上了解更多相关信息。


6
投票

并不是的。最常见的scala案例类是... scala类。

它们实际上是带有一些额外方法的常规scala类,它们会自动添加到它们中 - 即类本身上的.copy和伴随对象上的.apply.unapply。他们还得到一个很好的.toString方法,列出所有字段,和.equals,比较实例成员而不是对象ref。

在大多数其他方面,它们只是常规的scala类。


2
投票

Scala类就像Java类一样。他们的参考是通过价值传递的。

Scala案例类就像scala类,但有些东西会自动生成:

  • 构造函数的字段是公共可访问的(虽然case类默认是不可变的,因此你可以将它们视为Java中的public final值,除非你将case类的字段声明为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)
© www.soinside.com 2019 - 2024. All rights reserved.