3

この質問が以前に尋ねられたことはほぼ確実ですが、それを見つけるための適切な言葉がありません。

scala> Seq[Any]( 3, 3.4 )
res0: Seq[Any] = List(3, 3.4)

scala> res0( 1 ).getClass
res1: Class[_] = class java.lang.Double

scala> Seq( 3, 3.4 )
res2: Seq[Double] = List(3.0, 3.4)

scala> res2( 1 ).getClass
res3: Class[Double] = double

なぜ Scala は私のDouble入力をjava.lang.Doublea 内で処理するのに、 a で作業するときSeq[Any]はそれを保持するのですか? この動作を防ぎ、代わりに常に Scala 型を使用する方法はありますか?scala.DoubleSeq[AnyRef]

4

2 に答える 2

7

ScalaDoubleは Java に対応しますdoubleが、必要に応じて autoboxed および unboxed になるjava.lang.Double場合があり、autoboxed になったときになります。実際には、コレクションにはプリミティブ変数のオートボクシングが必要です。

型が明示的に宣言されていない場合、宣言するコレクションの型は、割り当てられた値に基づいて推測されます。問題の 2 つの宣言の違いは、Seq(value1,value2,...)型推論が「最適な」型を見つけようとし、この型 (Scala ) に基づいて思いついたSeq[Double]後、 intepretsvalue1などを実行することです。型を明示的に として宣言すると、型推論は実行されず (型を自分で指定したため)、値などは固定型として解釈されるように「強制」されません。value2DoubleSeq[Any]value1value2

はコレクションであるためSeq、プリミティブは許可されておらず、自動ボックス化する必要があります。そのため、Javadoubleは適合できませんjava.lang.Double。ボックス化とボックス化解除を隠そうとしSeq[Double]、プリミティブとオブジェクトを透過的に交換するロジックは機能しません。実際には、 aSeq[Any]では、各要素が異なるタイプである可能性があります。これは、そのようなボックス化とボックス化解除が一般的なケースでは機能しないことを意味します (例でres0(0).getClassは、 はDouble とはInteger対照的です)。res2(0).getClass

したがって、本質的に、型を明示的に宣言しない場合、型推論が開始され、最初にコレクションのすべての要素に共通の型を見つけようとし、次にすべての要素をその型にキャストし、コレクションの型パラメーターを明示的に指定します。そのようなことは起こらず、すべての値の型は「生」と解釈されます。

于 2013-08-27T20:11:59.153 に答える
4

起こっているのはボクシングです。最初は であるため、その中のSeq[Any]すべてのプリミティブはボックス化された形式で返されます。2 番目のケースでは、タイプがSeq[Double]であるため、メンバーへのアクセスは自動的にアンボックス化されます (ただし、ボックス化されて に保存されますSeq)。

プリミティブのランタイム クラスを取得しようとすると、あらゆる種類の問題が発生します。使用する必要がないことを試してくださいgetClass

于 2013-08-27T20:12:35.477 に答える