Scala:Nil vs List()

Scala:Nil vs List(),scala,Scala,在Scala中,Nil和List()之间有什么区别吗 如果不是,哪一个更为地道的Scala风格?用于创建新的空列表和空列表上的模式匹配 scala> println (Nil == List()) true scala> println (Nil eq List()) true scala> println (Nil equals List()) true scala> System.identityHashCode(Nil) 374527572 scala>

在Scala中,
Nil
List()
之间有什么区别吗

如果不是,哪一个更为地道的Scala风格?用于创建新的空列表和空列表上的模式匹配

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更为惯用,在大多数情况下更可取。
问题?

正如用户unknown的回答所示,它们是同一个对象

习惯用法上,Nil应该是首选,因为它又好又短。但有一个例外:如果出于我认为的任何原因需要显式类型

List[Foo]() 
他比我好

Nil : List[Foo]
已显示
Nil
List()
的运行时值相同。但是,它们的静态类型不是:

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)
                                               ^
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)
:10:错误:类型不匹配;
找到:列表[Int]
必需:scala.collection.immutable.Nil.type
列表(1,2,3).foldLeft(Nil)((x,y)=>y::x)
^

您可以提到
Nil
更为惯用。添加了System.identityHashCode以澄清“eq”已经说了什么-它们是同一个对象。此外,Nil直接引用一个对象,而List()是一个方法调用。
List[a]()
(而不是
Nil
)不需要作为foldLeft的累加器值吗?示例-
scala>Map(1->“hello”,2->“world”).foldLeft(List[String]()((acc,el)=>acc:+el.\u2)res1:List[String]=List(hello,world)
使用
Nil
作为累加器在这里是不起作用的。
Map(1->“hello”,2->“world”).foldLeft(Nil:List[String])(\uu:+.\uu 2)
还有
List.empty[Foo]
作为第三种选择。我不明白为什么2::Nil可以工作,但fold的累加器y::x@FUD嗯,
y::x
确实有效。问题是它返回的类型不是预期的类型。它返回
List[Int]
,而预期的类型是
List[Nothing]
Nil.type
(我认为是前者,但可能是后者)。