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でしょうか? +:すべてを操作できるようにしたいのに、なぜ使用する必要があるのSeqですか?

編集:私はパフォーマンスの議論を理解しています-私はこの質問をするたびにそれを与えられてきました-しかし、私はそれにほとんど同意しません. ::fromの削除という 1 つのことだけが変更された別のコレクション ライブラリを想像してみてくださいList。何が変わるでしょうか?

  • などを使用+:して、パフォーマンスの高い方法でリストを作成できます。Nil"A" +: "B" +: Nil
  • +:リストのさまざまな部分を抽出するために、エレガントなパターン マッチを使用できます。例えばcase head +: tail => println(head)
  • のすべてのサブクラスを構築およびパターン マッチングするための統一された方法がありSeqます。これにより、 で紹介したような微妙なバグをリンターで見つける必要がなくなりますgetTail

正直なところ、 を使用するよりも、 に固有のメソッドがどのようにList簡単、明確、またはパフォーマンスが向上するかわかりません+:。もしそうなら、 が に::限定される理由はないと思いますList。これを考えると、存在する理由がまったくわかりません::

4

1 に答える 1

3

すべてのクラス固有の演算子の背後にあるのと同じ理由。#::forStreamまたは!for のようにActor

シングルリンクと同様Listに、要素の先頭への追加と head + tail への分解は O(1) で実行されます。これは基本的に、リストに対して最もよく使用される操作です。List の全体的なアイデアは、この操作を中心に構築されています。

ListもサポートしてSeqいることに注意してください+:。しかし、使用することは、効率的な方法で::使用する意図を明確に示しています。List

于 2015-10-23T21:09:15.610 に答える