2017-06-17 49 views
4

所以我刚刚了解了scala case类,并且我被告知它们习惯于围绕一堆属性提供一个简单的包装,以便测试相等性。但现在我有两个问题:斯卡拉案例类 - 他们只是结构?

  • 这与C++/C#中的结构是一样的吗?
  • 案例类是一个值类型还是引用类型?

回答

5

首先,C++中的struct和C#中的struct是非常不同的东西。所以问的是scala中的case类与2件事情没有意义的相同。

  • 结构,C++就像是普通班,但在默认情况下,其成员 是公开的。有关此主题的更多信息,请参阅this post

  • C#中的结构是值类型。当作为参数传递时,它们被深拷贝而不是通过指针传递。这种行为与Java中的基本类型 类似。此行为是C++中的默认设置,可使用任何 classstruct

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

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

要给出更直接的答案,没有:

案例类是像普通班有几个关键的不同。

this page了解更多关于它们的内容。

5

不是。 Scala案例类最喜欢的是... scala类。

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

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

+0

他们还获得一个默认散列法。 –

2

Scala类就像Java类一样。它们的参考按值传递。

斯卡拉情况下类就像Scala类,但有些事情是为你自动生成:

  • 构造的领域是公开访问(尽管情况下此类默认为不可变的,所以你可以把它们看作是在Java中public final值,除非你声明的情况下班级为var的基础上,构造等领域的字段)
  • equalshashCode方法
  • 在同伴的applyunapply Method对象
  • 一个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) 
+0

案例类不一定是不可变的,虽然它们可以是'case class X(var x:Int); val xs = X(1); xs.x = 2; println(xs.x)//> 2' –