Antworten:
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 ist idiomatischer und kann in den meisten Fällen bevorzugt werden. Fragen?
List[A]()
(nicht Nil
) erforderlich? Beispiel - Die scala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world)
Verwendung Nil
als Akkumulator hier würde nicht funktionieren.
Map(1 -> "hello", 2 -> "world").foldLeft(Nil: List[String])( _ :+ _._2)
Unbekannter Benutzer hat gezeigt, dass der Laufzeitwert von beiden Nil
und List()
gleich ist. Ihr statischer Typ ist jedoch nicht:
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
Dies ist von besonderer Bedeutung, wenn es verwendet wird, um auf einen Typ zu schließen, z. B. im Akkumulator einer Falte:
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
funktioniert . Das Problem ist, dass der zurückgegebene Typ nicht der erwartete Typ ist. Es kehrt zurück List[Int]
, während der erwartete Typ entweder List[Nothing]
oder ist Nil.type
(ich denke der erstere, aber vielleicht der letztere).
Wie die Antwort des unbekannten Benutzers zeigt, handelt es sich um dasselbe Objekt.
Idiomatisch sollte Nil bevorzugt werden, weil es schön und kurz ist. Es gibt jedoch eine Ausnahme: Wenn aus irgendeinem Grund ein expliziter Typ benötigt wird, denke ich
List[Foo]()
ist schöner als
Nil : List[Foo]
List.empty[Foo]
eine dritte Alternative.
Nil
das idiomatischer ist.