2014-09-06 48 views
0

我使用反射來從延伸的調用的組件與以下調用特質類解析所有公共變量存取:帶來特質實現成員到範圍使用反射

def iterate[T <: Component : TypeTag : ClassTag](component: T) { 
    ... 
    ru.typeOf[T].members.filter(...) 
    ... 
} 

但是,這僅適用於如果類的類型實現組件的性狀在呼叫期間是可見的:

val myComp: MyComponent = new MyComponent() 
iterate(myComp) // works 

val myComp: Component = new MyComponent() 
iterate(myComp) // Doesn't work, no members of MyComponent found in scope 

一個解決辦法是在該性狀來定義執行類型(MyComponent的延伸成分[MyComponent的]),但由於我與反射周圍挖反正我想知道如果MyComponent的變量可以從特徵後面訪問。

回答

0

我想你可以從java.lang.Class得到Type。看下面的例子。

╰─$ scala 
Welcome to Scala version 2.11.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_65). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> :paste 
// Entering paste mode (ctrl-D to finish) 


import scala.reflect._ 
import scala.reflect.runtime.universe._ 

trait Component { 
    def parent: Int = 0 
} 
class MyComponent extends Component { 
    def child: Int = 0 
} 
def printRuntimeMemberNames(component: Component) = { 
    val cls = component.getClass 
    val mirror = runtimeMirror(cls.getClassLoader) 
    val symbol = mirror.staticClass(cls.getName) 
    val tpe = symbol.toType 
    val members = tpe.members 
    val memberNames = members.map(_.name.decodedName.toString) 
    println(memberNames.mkString(", ")) 
} 


// Exiting paste mode, now interpreting. 

import scala.reflect._ 
import scala.reflect.runtime.universe._ 
defined trait Component 
defined class MyComponent 
printRuntimeMemberNames: (component: Component)Unit 

scala> val c: Component = new MyComponent 
c: Component = [email protected] 

scala> printRuntimeMemberNames(c) 
<init>, child, parent, $init$, $asInstanceOf, $isInstanceOf, synchronized, ##, !=, ==, ne, eq, notifyAll, notify, clone, getClass, hashCode, toString, equals, wait, wait, wait, finalize, asInstanceOf, isInstanceOf