是否可以在创建对象后获取类型字段的类型?

问题描述:

创建对象后可以获取类型字段的类型吗?是否可以在创建对象后获取类型字段的类型?

我愿做这样的事情:

scala> class A { type T = String } 
defined class A 

scala> val a = new A 
a: A = [email protected] 

scala> a.T 
<console>:13: error: value T is not a member of A 
      a.T 
      ^

最后

一种方法是用反射(因为2.10M4):

// with static types 
scala> class A { type T = String } 
defined class A 

scala> import reflect.runtime.{universe => u} 
import reflect.runtime.{universe=>u} 

scala> val t = u.typeOf[A] 
t: reflect.runtime.universe.Type = A 

scala> val types = t.declarations.filter(_.isType) 
types: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(type T) 

scala> types.toList.head.typeSignature 
res9: reflect.runtime.universe.Type = String 

// with instances 
scala> val a = new A 
a: A = [email protected] 

scala> import reflect.runtime.{currentMirror => m} 
import reflect.runtime.{currentMirror=>m} 

scala> m.reflect(a).symbol.asType // same type as t 
res20: reflect.runtime.universe.Type = A 
+0

谢谢。是否可以在2.10之前(没有反思)? –

+0

我不这么认为(或者至少不是以一种干净的方式)。 JVM-Bytecode不知道类型成员,并且存在类型擦除。两者都使得获取类型成员的具体类型非常困难。 – sschaef

+0

@Antoras炫耀。 ;-) –

你有什么想做的事与类型?您可以使用与类的类型各种方式型投影(没有实例):

scala> class A { type T = String } 
defined class A 

scala> val x: A#T = "test" 
x: java.lang.String = test 

scala> def f(b: A#T) = b 
f: (a: java.lang.String)java.lang.String 

或者,如果您启用-Ydependent-method-types,您可以从实例获取类型成员:

scala> val a = new A 
a: A = [email protected] 

scala> val x: a.T = "test" 
x: a.T = test 

scala> def f(b: a.T) = b 
f: (b: a.T)a.T 

Scala的在2.10之前的反射API并没有以任何干净的方式真正模拟类型,所以如果你想从某种其他意义上“获得类型”,你可能运气不好。