Scala清单取自变量而不是实例?

时间:2013-09-24 17:01:03

标签: scala manifest

我不太确定如何说出这个问题,因为我真的不明白发生了什么。但是我希望清单能够告诉我实例的实际运行时类型,它似乎告诉我它所分配的变量的运行时类型。

// 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]结束?有没有解决方法,以便我可以在编译时选择一个我不知道的类型(由config参数等选择)并将其传递给工厂方法?

1 个答案:

答案 0 :(得分:2)

这似乎对我有所期待。在您调用showManifest的所有实例中,您将推迟使用类型推断来确定类型,而不是明确传入类型(即showManifest[Impl1](impl1))。因此,您看到与清单绑定的类型将与您传入的val类型相匹配。在前两种情况下,类型推断知道确切的具体类型,您会看到反映在showManifest打印的内容中。在后两种情况下,由于条件,类型推断在编译时并不完全知道它将最终成为哪一个,因此它向上移动这两种类型的类型层次结构,直到它找到一个最终为{的公共类型为止{ {1}}。

我想如果你想尝试绕过这种行为,你可以尝试这样的事情:

Base

此外,您应该将内容转换为import scala.reflect.ManifestFactory showManifest(choose1)(ManifestFactory.classType(choose1.getClass())) s / TypeTag s,因为Scala 2.10中已弃用ClassTag