Scala:Nil vs List()


128

在Scala中,Nil和之间是否有任何区别List()

如果不是,哪一种是更惯用的Scala风格?用于创建新的空列表和在空列表上进行模式匹配。

Answers:


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更惯用,在大多数情况下可能更受欢迎。有什么问题吗


11
您可能会提到,这Nil更惯用了。
雷克斯·克尔

6
添加了System.identityHashCode来阐明“ eq”已经说的内容-它们是同一对象。
James Iry

18
此外,Nil直接引用对象,而List()是方法调用。
Jean-Philippe Pellet

6
是不是List[A]()(不Nil)需要为foldLeft累加器值?示例- scala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world)使用Nil此作为蓄能器是行不通的。
凯文·梅瑞迪斯

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

85

未知的用户表明,两者的运行时间值NilList()是相同的。但是,它们的静态类型不是:

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

当用于推断类型时,例如在折叠的累加器中,这一点尤其重要:

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

我不明白为什么2 :: Nil起作用,但不折叠倍数的累加器y :: x
FUD

2
@FUD好,y :: x 确实可以。问题在于它返回的类型不是预期的类型。它返回List[Int],而预期的类型为List[Nothing]or或Nil.type(我认为是前者,但也许是后者)。
Daniel C. Sobral

27

如未知用户的答案所示,它们是同一对象。

通常,应该首选Nil,因为它又好又矮。但是有一个例外:如果我出于任何原因需要显式类型

List[Foo]() 

比...好

Nil : List[Foo]

36
还有List.empty[Foo]第三种选择。
卡森斯2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.