4

使::特定List于所有子类而不适用于所有子类的原因是Seq什么?举一个具体的例子:

// :: for pattern matching
def getTail[E](s: Seq[E]): Seq[E] = s match {
   case head :: tail => tail
   case empty => empty
}
getTail(Seq(1, 2)) // returns List(2) as expected
getTail(Seq()) // returns List() as expected
getTail(Queue(1, 2)) // returns Queue(1, 2), not Queue(2)
getTail(Buffer(1, 2)) // returns ArrayBuffer(1, 2), not ArrayBuffer(2)

// :: for building sequences
1 :: 2 :: 3:: Nil // Creates List(1, 2, 3)
1 :: 2 :: List(3) // same as above
1 :: 2 :: Queue(3) // does not compile. :: is not a method within Queue

所有序列都是有序的,并且有“头”和“尾”的概念,那么为什么集合库的实现者只提供::List? +:如果我想能够与 all 一起工作,为什么必须使用Seq

编辑:我理解性能论点——几乎每次我问这个问题时都会得到它——但我在很大程度上不同意它。想象一个不同的集合库,其中只有一件事发生了变化:删除::from List。会发生什么变化?

  • 我仍然可以使用+:诸如.Nil"A" +: "B" +: Nil
  • 我仍然可以优雅地使用模式匹配+:来提取列表的不同部分。例如case head +: tail => println(head)
  • 有一个统一的方法来构建和模式匹配的所有子类Seq。这消除了使用 linter 来查找细微错误的需要,例如我在getTail.

老实说,我没有看到独特的方法如何List使任何事情变得更容易、更清晰或比使用+:. 如果是这样的话,那么我认为没有理由::具体到List. 鉴于此,我根本看不到存在的理由::

4

1 回答 1

3

与所有特定于类的运算符背后的推理相同。喜欢#::forStream!for Actor

List单链接一样,在 O(1) 中执行前置元素和解构到头 + 尾。它基本上是列表最常用的操作。List 的整个思想就是围绕这个操作构建的。

请注意,它也List支持Seq's +:。但是使用::清楚地表明您打算以List有效的方式使用。

于 2015-10-23T21:09:15.610 回答