7

In scala source, I found:

case object Nil extends List[Nothing] {
    ...
}

I can't understand why it is declared as case object rather than object?

I found this question [ Difference between case object and object ] is useful, and I guess this reason is the key:

default implementations of serialization

because we often send list of data to another actor, so Nil must be serializable, right?


With the provided answers(thanks), I try to write some code to verify it:

trait MyList[+T]

object MyNil extends MyList[Nothing]

val list: MyList[String] = MyNil

list match {
  case MyNil => println("### is nil")
  case _ => println("### other list")
}

You can see MyNil is not case object, but I can still use it in pattern matching. Here is the output:

### is nil

Do I misunderstand something?

Community
  • 1
  • 1
Freewind
  • 193,756
  • 157
  • 432
  • 708

2 Answers2

5

In general for immutable data, the question should never be "why is this a case object (or class)" but rather "Can I make this a case object?". With a few small exceptions (mostly due to inheritance), data elements in Scala should be immutable, and should be implemented via case classes/objects. Given that, implementing Nil and :: as a case object and case class (respectively) is just standard practice, for which there is no downside.

Dave Griffith
  • 20,435
  • 3
  • 55
  • 76
2

As mentioned in the comments of that linked question, one thing you get is a prettier .toString result

scala> MyNil.toString
res0: String = MyNil$@51aa572b

scala> case object MyNil2 extends MyList[Nothing]
defined module MyNil2

scala> MyNil2.toString
res2: String = MyNil2

scala> Nil.toString
res1: String = List()
Bobby
  • 18,217
  • 15
  • 74
  • 89