1

何が起こっているのかよくわからないので、この質問の言い方がよくわかりません。しかし、マニフェストがインスタンスの実際の実行時の型を教えてくれると期待するところでは、それが割り当てられている変数の実行時の型を教えてくれているようです。

// scala 2.10.1
trait Base
class Impl1 extends Base
class Impl2 extends Base

def showManifest[T <: Base](thing: T)(implicit ev: Manifest[T]) = println(thing + ": " + ev.runtimeClass)

val (impl1, impl2) = (new Impl1, new Impl2)

println("=== impl1 and impl2 ===")
showManifest(impl1)
showManifest(impl2)

val choose1 = if(true) impl1 else impl2
val choose2 = if(false) impl1 else impl2

println("=== choose1 and choose2 ===")
showManifest(choose1)
showManifest(choose2)

出力:

=== impl1 and impl2 ===
Main$$anon$1$Impl1@48ff2413: class Main$$anon$1$Impl1
Main$$anon$1$Impl2@669980d5: class Main$$anon$1$Impl2
=== choose1 and choose2 ===
Main$$anon$1$Impl1@48ff2413: interface Main$$anon$1$Base
Main$$anon$1$Impl2@669980d5: interface Main$$anon$1$Base

では、choose1 と choose2 の型は Base ですが、メソッドが Manifest[Base] になるのはなぜですか? これを回避する方法はありますか? コンパイル時にわからない型 (構成パラメーターなどで選択) を選択し、それをファクトリ メソッドに渡すことができますか?

4

1 に答える 1

2

これはすべて、期待どおりに機能しているようです。を呼び出すすべてのインスタンスshowManifestで、型を明示的に渡すのではなく、型の推定を延期して型を決定します (つまり、showManifest[Impl1](impl1))。したがって、マニフェストに結び付けられている型は、val渡されている型と一致します。最初の 2 つのケースでは、型推論は正確な具象型を認識し、それが出力に反映されていることがわかりますshowManifest。2 番目の 2 つのケースでは、条件があるため、型推論はコンパイル時にどちらになるかを正確に認識していないため、最終的に になる共通の型が見つかるまで、これら 2 つの型の型階層を上に移動しますBase

この動作を回避したい場合は、次のようなことを試すことができると思います。

import scala.reflect.ManifestFactory
showManifest(choose1)(ManifestFactory.classType(choose1.getClass()))

また、 Scala 2.10 で廃止されたので、おそらくTypeTags/ ClassTagsに切り替える必要があります。Manifest

于 2013-09-24T17:22:22.940 に答える