4

あなたがタイプするとき、私はそれを知っています:

val list = List(2,3)

Listを返すListオブジェクトのapplyメソッドにアクセスしています。私が理解できないのは、Listクラスが抽象であり、したがって直接インスタンス化できない場合(new List()がコンパイルされない場合)にこれが可能である理由です。また、次の違いは何ですか?

val arr = Array(4,5,6)

val arr = new Array(4, 5, 6)
4

2 に答える 2

7

Listクラスはとsealedですabstract。2つのconcreate実装があります

  1. Nilこれは空のリストを表します
  2. ::[B]これは、頭と尾を持つ空でないリストを表します。::[B]ドキュメントで

電話をかけるList.applyと、いくつかのフープを飛び越えて、::[B]ケースクラスのインスタンスが提供されます。

配列について:配列new Array(4, 5, 6)のコンストラクターが次のように定義されているため、コンパイルエラーがスローされますnew Array(_length: Int)。コンパニオンオブジェクトのapplyメソッドは、引数を使用して(の助けを借りて)Arrayの新しいインスタンスを作成します。ArrayArrayBuilder

于 2013-02-25T11:33:43.730 に答える
6

これを判断する簡単な方法は、呼び出しているメソッドのソースを調べることであると書き始めました。これは、ScalaDocから入手できます。ただし、実際にリストを作成するために通過するさまざまなレベルの間接参照は、「簡単」という用語に嘘をつきます。必要に応じて、次のように定義されているオブジェクトのapplyメソッドから始めて、一読する価値があります。List

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

xs : A*フォームのパラメータが内部的にとして扱われることを知っているかもしれませんし、知らないかもしれません。つまり、で定義されている、でメソッドをSeq呼び出しているということです。次に、これはジェネリックメソッドに委任します。このメソッドは、実際にリストを作成する暗黙的 なメソッドを探します。したがって、返されるのは、によって選択された実装です。実際に取得するのは、単一リンクリストを実装するです。toListSeqTraversableOncetoCanBuildFromListCanBuildFromscala.collection.immutable.$colon$colon

幸いなことに、の動作Array.applyは少し簡単に調べることができます。

  def apply[T: ClassTag](xs: T*): Array[T] = {
    val array = new Array[T](xs.length)
    var i = 0
    for (x <- xs.iterator) { array(i) = x; i += 1 }
    array
  }

したがって、要素を適切Array.applyに委任してから設定するだけです。new Array

于 2013-02-25T11:37:13.840 に答える