It cannot be initialized with params and it will only be compared with itself (singleton). So no advantage for its equals and hash code function. Has anyone come across a case where they find it useful?
Asked
Active
Viewed 2,667 times
5
-
5"Has anyone come across a CASE where...". Heh. I chuckled. – Jakob Sep 16 '15 at 07:34
-
It's useful when you want to define an algebraic datatype : https://gleichmann.wordpress.com/2011/01/30/functional-scala-algebraic-datatypes-enumerated-types/ – alifirat Sep 16 '15 at 08:16
-
2For example: `None` is `case object`. Actually, you use case objects when some instance of your `algebraic datatype` should be distinguished but has no any parameters. Like `Option`, `Some(v)` is `case class`, but `None` is just `None` without state. For why `case` is useful see: http://stackoverflow.com/questions/5270752/difference-between-case-object-and-object – dmitry Sep 16 '15 at 08:48
-
There are lot of case objects used in `akka` as message, like `PoisonPill` , `Tick`, and so on. – ymonad Sep 16 '15 at 09:03
-
@dmitry please add it as an answer! – Dragonborn Sep 16 '15 at 09:20
2 Answers
10
You can use case objects as an alternative for enumerations.
Details can be found here: Case objects vs Enumerations in Scala
A simplified example from that question:
sealed trait Currency {
def name: String
def symbol: String
}
case object EUR extends Currency {
val name = "EUR"
val symbol = "€"
}
case object USD extends Currency {
val name = "USD"
val symbol = "$"
}
Advantages
- This way there can be more fields (compared to ID and name in an
Enumeration
) - The compiler warns (in case of a
sealed
type hierarchy), if a match is not exhaustive.
So this code
val ccy: Currency = EUR
ccy match {
case EUR =>
println("Euro")
}
will result in
Warning:(27, 7) match may not be exhaustive.
It would fail on the following inputs: USD
ccy match {
Disadvantages
- There is no "get by name" method (
Enumeration
provideswithName()
) - You cannot iterate over "all" elements
5
I think the most important difference is that case objects can be serialized while simple objects cannot.
This makes them very useful as messages with Akka-Remote.
EDIT:
As Rüdiger Klaehn pointed out, this is not the only benefit we get from the case
keyword. There is also:
- hashCode implementation
- a useful toString implementation
For classes additionally:
- pattern matching optimization
- a companion object with useful
apply
andunapply
implementations
(This list may not be exhaustive!)

Community
- 1
- 1

Sascha Kolberg
- 7,092
- 1
- 31
- 37
-
A case object will also have hashCode and toString implemented. So `case object Foo; foo.toString` will give just Foo, whereas `object Foo; Foo.toString` will give something like Foo$@1bb485e7 (different at each run!). Same for hashCode: the hashCode of a case object will be the same in different JVM processes. – Rüdiger Klaehn Sep 16 '15 at 08:54
-
-
@Dragonborn On the contrary: The case keyword makes a class/object `Serializable` (amongst other things). – Sascha Kolberg Sep 16 '15 at 09:16
-
@Dragonborn even in scala 2.10.4 a `case class` is serializable. At least you can serialize instances of a `case class` with `java.io.ObjectOutputStream.writeObject()`. – Sascha Kolberg Sep 16 '15 at 09:30