我正在学习Scala(编程Scala,第2版,Odersky)。
使用cons运算符构建列表时,我们必须写:
val l = 1 :: 2 :: 3 :: 4 :: Nil
为什么我们最后需要Nil?为什么编译器不能理解4是最后一个元素,所以只需编写它:
val l = 1 :: 2 :: 3 :: 4
答案 0 :(得分:8)
::
的签名大致是:
case class ::[E](hd: E, tl: List[E]) extends List[E]
// which generates this automatically:
object :: {
def apply[E](hd: E, tl: List[E]): ::[E]
}
Nil
的签名大致是:
object Nil extends List[Nothing]
如您所见,::
包含元素和列表。 4
不是列表,而Nil
是。
答案 1 :(得分:2)
实际上,你可以自己动手:
scala> implicit class Listable[A](val value: A) {
| def ::[B >: A](other: B): List[B] = other :: value :: Nil
| }
defined class Listable
scala> val xs = 1 :: 2 :: 3 :: 4
xs: List[Int] = List(1, 2, 3, 4)
scala> val ys = "A" :: "B" :: "C"
ys: List[String] = List(A, B, C)
scala>
答案 2 :(得分:1)
从概念上讲,Scala中的列表是
::
将创建一个包含头元素和尾元素列表的新列表。这是正确的关联。
所以
1 :: 2 :: 3 :: 4 :: Nil
将被编译为
1 :: (2 :: (3 :: (4 :: Nil)))
从右边开始,第一个列表由4和Nil构成,从而创建一个新列表[4]。然后添加3作为尾部列表的头[4],制作一个新列表[3,4]。等等...
要回答您的问题,Scala需要一个空列表来构造第一个列表。原因就是在Scala中定义列表的方式。