Scala: Nil vs List ()


128

Trong Scala, có sự khác biệt nào giữa NilList()không?

Nếu không, cái nào là phong cách Scala hơn? Cả hai để tạo danh sách trống mới và khớp mẫu trên danh sách trống.

Câu trả lời:


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 là thành ngữ hơn và có thể được ưa thích trong hầu hết các trường hợp. Câu hỏi?


11
Bạn có thể đề cập đến đó Nillà thành ngữ hơn.
Rex Kerr

6
Đã thêm System.identityHashCode để làm rõ những gì "eq" đã nói - chúng là cùng một đối tượng.
James Iry

18
Ngoài ra, Nil trực tiếp tham chiếu một đối tượng, trong khi List () là một cuộc gọi phương thức.
Jean-Philippe Pellet

6
Không List[A]()(không Nil) cần thiết như một giá trị tích lũy cho FoldLeft? Ví dụ - scala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world)Sử dụng Nillàm công cụ tích lũy ở đây sẽ không hoạt động.
Kevin Meredith

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

84

Người dùng chưa biết đã chỉ ra rằng giá trị thời gian chạy của cả hai NilList()giống nhau. Tuy nhiên, kiểu tĩnh của chúng không phải là:

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

Điều này đặc biệt quan trọng khi nó được sử dụng để suy ra một loại, chẳng hạn như trong bộ tích lũy của nếp gấp:

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

tôi không hiểu tại sao 2 :: Nil hoạt động nhưng không gấp được tích lũy y :: x
FUD

2
@FUD Vâng, y :: x không hoạt động. Vấn đề là loại nó trả về không phải là loại mong đợi. Nó trả về List[Int], trong khi loại dự kiến ​​là List[Nothing]hoặc Nil.type(tôi nghĩ cái trước, nhưng có thể cái sau).
Daniel C. Sobral

27

Như câu trả lời của người dùng chưa biết, chúng là cùng một đối tượng.

Nil idiomatic nên được ưa thích vì nó là tốt đẹp và ngắn. Mặc dù có một ngoại lệ: nếu tôi cần một loại rõ ràng vì bất kỳ lý do gì tôi nghĩ

List[Foo]() 

đẹp hơn

Nil : List[Foo]

36
Cũng có List.empty[Foo]một sự thay thế thứ ba.
kassens
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.