Scala Case Classes - Are they just structs?

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 pass by value or pass by reference?

4 answers

  • answered 2017-06-17 18:01 Winter

    First, a struct in C++ and a struct in C# are very different things. So asking is case classes in scala are the same as those 2 things does not make sense.

    • 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 deeply copied instead of passed via a pointer. This behavior is similar to a primitive type in Java. This behavior 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 completly 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 behavior 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.

  • answered 2017-06-17 18:01 Dima

    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.

  • answered 2017-06-17 18:01 Zoltán

    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, thus you can regard them as public final values in Java)
    • 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)

  • answered 2017-06-17 18:01 abhi

    There are already some great answers, but I hope I can provide some more information to help.

    To briefly answer both questions at once before going into detail, no, they are not the same and case classes are pass by value.

    The reason why case classes are pass-by-value is because Scala, like Java, is based on the JVM and the value passed around is either a pointer to an object, or a primitive altogether. You could think of case classes as immutable objects that hold data for pattern matching, and do away with boilerplate code for implementing algebraic data types. There are other usages for them as mentioned in other answers, the only one that I do not see mentioned yet:

    • Automatic definition of getter methods for constructor arguments