Risposte:
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
Lo zero è più idiomatico e può essere preferito nella maggior parte dei casi. Domande?
List[A]()
(non Nil
) necessario come valore dell'accumulatore per foldLeft? Esempio - L' scala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world)
uso Nil
come accumulatore qui non funzionerebbe.
Map(1 -> "hello", 2 -> "world").foldLeft(Nil: List[String])( _ :+ _._2)
L'utente sconosciuto ha dimostrato che il valore di runtime di entrambi Nil
e List()
sono gli stessi. Tuttavia, il loro tipo statico non è:
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
Ciò è di particolare importanza quando viene utilizzato per inferire un tipo, come nell'accumulatore di una piega:
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)
^
y :: x
fa il lavoro. Il problema è che il tipo che restituisce non è il tipo previsto. Restituisce List[Int]
, mentre il tipo previsto è o List[Nothing]
o Nil.type
(penso il primo, ma forse il secondo).
Come mostra la risposta dell'utente sconosciuto, sono lo stesso oggetto.
Idiomaticamente zero dovrebbe essere preferito perché è bello e corto. C'è comunque un'eccezione: se è necessario un tipo esplicito per qualsiasi motivo, penso
List[Foo]()
è più bello di
Nil : List[Foo]
List.empty[Foo]
una terza alternativa.
Nil
è più idiomatico.