あなたがタイプするとき、私はそれを知っています:
val list = List(2,3)
Listを返すListオブジェクトのapplyメソッドにアクセスしています。私が理解できないのは、Listクラスが抽象であり、したがって直接インスタンス化できない場合(new List()がコンパイルされない場合)にこれが可能である理由です。また、次の違いは何ですか?
val arr = Array(4,5,6)
と
val arr = new Array(4, 5, 6)
あなたがタイプするとき、私はそれを知っています:
val list = List(2,3)
Listを返すListオブジェクトのapplyメソッドにアクセスしています。私が理解できないのは、Listクラスが抽象であり、したがって直接インスタンス化できない場合(new List()がコンパイルされない場合)にこれが可能である理由です。また、次の違いは何ですか?
val arr = Array(4,5,6)
と
val arr = new Array(4, 5, 6)
List
クラスはとsealed
ですabstract
。2つのconcreate実装があります
Nil
これは空のリストを表します::[B]
これは、頭と尾を持つ空でないリストを表します。::[B]
ドキュメントで電話をかけるList.apply
と、いくつかのフープを飛び越えて、::[B]
ケースクラスのインスタンスが提供されます。
配列について:配列new Array(4, 5, 6)
のコンストラクターが次のように定義されているため、コンパイルエラーがスローされますnew Array(_length: Int)
。コンパニオンオブジェクトのapply
メソッドは、引数を使用して(の助けを借りて)Array
の新しいインスタンスを作成します。Array
ArrayBuilder
これを判断する簡単な方法は、呼び出しているメソッドのソースを調べることであると書き始めました。これは、ScalaDocから入手できます。ただし、実際にリストを作成するために通過するさまざまなレベルの間接参照は、「簡単」という用語に嘘をつきます。必要に応じて、次のように定義されているオブジェクトのapply
メソッドから始めて、一読する価値があります。List
override def apply[A](xs: A*): List[A] = xs.toList
xs : A*
フォームのパラメータが内部的にとして扱われることを知っているかもしれませんし、知らないかもしれません。つまり、で定義されている、でメソッドをSeq
呼び出しているということです。次に、これはジェネリックメソッドに委任します。このメソッドは、実際にリストを作成する暗黙的
なメソッドを探します。したがって、返されるのは、によって選択された実装です。実際に取得するのは、単一リンクリストを実装するです。toList
Seq
TraversableOnce
to
CanBuildFrom
List
CanBuildFrom
scala.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