Scala: Nil vs List()
In Scala, is there any difference at all between Nil
and List()
?
If not, which one is more idiomatic Scala style? Both for creating new empty lists and pattern matching on empty lists.
Solution 1:
scala> println (Nil == List())
true
scala> println (Nil eq List())
true
scala> println (Nil equals List())
true
scala> System.identityHashCode(Nil)
374527572
scala> System.identityHashCode(List())
374527572
Nil is more idiomatic and can be preferred in most cases. Questions?
Solution 2:
User unknown has shown that the run time value of both Nil
and List()
are the same. However, their static type is not:
scala> val x = List()
x: List[Nothing] = List()
scala> val y = Nil
y: scala.collection.immutable.Nil.type = List()
scala> def cmpTypes[A, B](a: A, b: B)(implicit ev: A =:= B = null) = if (ev eq null) false else true
cmpTypes: [A, B](a: A, b: B)(implicit ev: =:=[A,B])Boolean
scala> cmpTypes(x, y)
res0: Boolean = false
scala> cmpTypes(x, x)
res1: Boolean = true
scala> cmpTypes(y, y)
res2: Boolean = true
This is of particular importance when it is used to infer a type, such as in a fold's accumulator:
scala> List(1, 2, 3).foldLeft(List[Int]())((x, y) => y :: x)
res6: List[Int] = List(3, 2, 1)
scala> List(1, 2, 3).foldLeft(Nil)((x, y) => y :: x)
<console>:10: error: type mismatch;
found : List[Int]
required: scala.collection.immutable.Nil.type
List(1, 2, 3).foldLeft(Nil)((x, y) => y :: x)
^
Solution 3:
As user unknown's answer shows, they are the same object.
Idiomatically Nil should be preferred because it is nice and short. There's an exception though: if an explicit type is needed for whatever reason I think
List[Foo]()
is nicer than
Nil : List[Foo]