Scala中::和Nil类型之间的区别

时间:2019-03-04 09:22:11

标签: scala list subclass

我正在学习Scala并使用List并按如下方式创建字符串列表:

val myList = List("Laptop", "Mouse", "Keyboard", "screen")

从文档中,我得到:

  

scala包中的抽象类List,它带有::和Nil的两个子类

从类定义中我得到:

@SerialVersionUID(509929039250432923L) // value computed by serialver for 2.11.2, annotation added in 2.11.4
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
  override def tail : List[B] = tl
  override def isEmpty: Boolean = false
}

@SerialVersionUID(0 - 8256821097970055419L)
case object Nil extends List[Nothing] {
  override def isEmpty = true
  override def head: Nothing =
    throw new NoSuchElementException("head of empty list")
  override def tail: List[Nothing] =
    throw new UnsupportedOperationException("tail of empty list")
  // Removal of equals method here might lead to an infinite recursion similar to IntMap.equals.
  override def equals(that: Any) = that match {
    case that1: scala.collection.GenSeq[_] => that1.isEmpty
    case _ => false
  }
}

但是文档没有显示何时创建NIL对象以及何时创建::子类对象。

两者之间有什么区别,请建议何时使用::子类以及何时使用NIL子类?

1 个答案:

答案 0 :(得分:2)

使用List(..)语法时,编译器将使用List.apply的伴随对象中定义的List

override def apply[A](xs: A*): List[A] = xs.toList

您实际上看不到列表的创建,因为它是根据Scala集合库的定义方式通用创建的。

::Nil之间的区别在于,前者代表具有头和尾的链表,后者代表不包含任何元素的空列表。

我们还可以直接使用::Nil来定义列表:

val list = "Laptop" :: "Mouse" :: "Keyboard" :: Nil

哪个翻译为:

val list = Nil.::("Keyboard").::("Mouse").::("Laptop")

::不是引用类型::,而是引用List[A]上的方法:

def ::[B >: A] (x: B): List[B] = new scala.collection.immutable.::(x, this)