Scala: Nil vs List ()


128

Dalam Scala, apakah ada perbedaan sama sekali antara Nildan List()?

Jika tidak, gaya Scala mana yang lebih idiomatis? Baik untuk membuat daftar kosong baru dan pencocokan pola pada daftar kosong.

Jawaban:


188
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 lebih idiomatik dan dapat lebih disukai dalam banyak kasus. Pertanyaan?


11
Anda bisa mengatakan itu Nillebih idiomatis.
Rex Kerr

6
Ditambahkan System.identityHashCode untuk mengklarifikasi apa yang "eq" sudah katakan - mereka objek yang sama.
James Iry

18
Selain itu, Nil merujuk objek secara langsung, sedangkan List () adalah pemanggilan metode.
Jean-Philippe Pellet

6
Bukankah List[A]()(tidak Nil) diperlukan sebagai nilai akumulator untuk foldLeft? Contoh - scala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world)Menggunakan Nilsebagai akumulator di sini tidak akan berfungsi.
Kevin Meredith

6
Map(1 -> "hello", 2 -> "world").foldLeft(Nil: List[String])( _ :+ _._2)
Raul

85

Pengguna yang tidak dikenal telah menunjukkan bahwa nilai waktu berjalan keduanya Nildan List()sama. Namun, tipe statis mereka bukan:

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

Ini sangat penting ketika digunakan untuk menyimpulkan suatu tipe, seperti dalam akumulator lipatan:

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)
                                               ^

saya tidak mengerti mengapa 2 :: Nil bekerja tetapi bukan akumulator lipat y :: x
FUD

2
@FUD Nah, y :: x tidak bekerja. Masalahnya adalah bahwa jenis yang dikembalikan bukan jenis yang diharapkan. Itu kembali List[Int], sementara jenis yang diharapkan adalah salah satu List[Nothing]atau Nil.type(saya pikir yang pertama, tapi mungkin yang terakhir).
Daniel C. Sobral

27

Seperti yang ditunjukkan oleh jawaban yang tidak diketahui pengguna, mereka adalah objek yang sama.

Secara nihil Nil harus dipilih karena bagus dan pendek. Namun ada pengecualian: jika jenis eksplisit diperlukan untuk alasan apa pun yang saya pikirkan

List[Foo]() 

lebih baik daripada

Nil : List[Foo]

36
Ada juga List.empty[Foo]sebagai alternatif ketiga.
kassens
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.