6

So I just learned about scala case classes, and I'm told they are used to provide a simple wrapper around a bunch of properties so that it's easier to test for equality. But now I have two questions:

  • Is this just the same thing as a struct in C++/C#?
  • Are case classes a value type or a reference type?
user3685285
  • 6,066
  • 13
  • 54
  • 95

3 Answers3

8

First note that a struct in C++ and a struct in C# are very different things.

  • Structures in C++ are just like regular classes but by default, their members are public. See this post for more on this topic.

  • Structures in C# are value types. When passed as a parameter, they are copied instead of passed via a pointer. This behaviour is similar to a primitive type in Java. This behaviour is the default in C++, with any class or struct.

Your second question has been answered in Eric's answer but the important point is that C# structures are passed completely by value (all their fields are copied) while Java/C# classes are passed via a pointer (that is passed by value). See this famous post if you want the full explanation.

Unfortunately, it is not currently possible to have a true value type in JVM bytecode. You cannot make your own type that will be fully copied everytime you pass it. And the answer is no, case classes aren't value types like C# structures. A JVM language may try to replicate the behaviour of a value type but it will be managed by the GC and passed via a pointer (that is passed by value).

To give a more direct answer, no:

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

Learn more about them on this page.

Winter
  • 3,894
  • 7
  • 24
  • 56
  • I would avoid saying "deeply" copied because that might imply the wrong thing when talking about `struct`s that hold pointers in C++. It's technically a "shallow" copy. :) – Erich Gubler Mar 29 '19 at 20:27
  • @ErichGubler Indeed, fixed the mistake. – Winter Mar 30 '19 at 19:19
7

Not really. What scala case classes are most like is ... scala classes.

They actually are regular scala classes with a few additional methods, that get added to them automatically - namely, .copy on the class itself and .apply and .unapply on the companion object. They also get a nice .toString method, listing all the fields, and .equals, that compares instance members rather than the object ref.

In most other respects, they are just regular scala classes.

Dima
  • 39,570
  • 6
  • 44
  • 70
2

Scala classes are just like Java classes. Their reference is passed by value.

Scala case classes are just like scala classes, but some things are automatically generated for you:

  • The fields of the constructor are publicly accessible (albeit a case class is immutable by default, thus you can regard them as public final values in Java, unless you declare the fields of the case class as var)
  • An equals and hashCode method based on the fields of the constructor
  • An apply and unapply method in the companion object
  • A toString method showing all the values of the constructor
  • A copy method

Here's an example:

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)
Zoltán
  • 21,321
  • 14
  • 93
  • 134