5

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?

Dragonborn
  • 1,755
  • 1
  • 16
  • 37
  • 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
  • 2
    For 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 Answers2

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 provides withName())
  • You cannot iterate over "all" elements
Community
  • 1
  • 1
Beryllium
  • 12,808
  • 10
  • 56
  • 86
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 and unapply 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
  • wait a case keyword will not make the class serializable right? – Dragonborn Sep 16 '15 at 09:14
  • @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