2013-05-03 59 views
8

使用實驗性的Scala 2.10反射,當我嘗試在一個惰性val字段上調用FieldMirror.get()時,它返回null。有沒有一種方法來評估使用反射的惰性val? get()函數不應該再返回null。如何使用反射評估惰性val?

考慮這個例子:

case class Person(val firstName: String, 
        val lastName: String) { 
    lazy val name = firstName + " " + lastName 
} 

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

val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader) 

val fred = Person("Fred", "Smith") 

val instanceMirror = runtimeMirror.reflect(fred) 

val nameTerm = ru.typeOf[Person].declaration(ru.newTermName("name")).asTerm 

val nameLazy = instanceMirror.reflectField(nameTerm) 

nameLazy.get 
    >>> res8: Any = null 

fred.name 
    >>> res9: String = Fred Smith 

nameLazy.get 
    >>> res10: Any = Fred Smith 
+0

強制評估該懶惰表達式。我不知道斯卡拉的具體情況。 – 2013-05-03 14:30:02

+0

在這一點上,我只有一個懶惰的val - 一個FieldMirror的參考 - 所以我不能簡單地評估它。 get()函數返回表達式,然後我可以輕鬆評估它。 – vertexshader 2013-05-03 14:35:26

回答

6

我發現瞭解決方案。有一個隱藏的方法會生成:

case class Person(val firstName: String, 
       val lastName: String) { 
lazy val name = firstName + " " + lastName 
} 

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

val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader) 

val fred = Person("Fred", "Smith") 

val instanceMirror = runtimeMirror.reflect(fred) 

val nameMethod = ru.typeOf[Person].member(ru.newTermName("name")).asMethod 
val nameValue = ru.typeOf[Person].member(ru.newTermName("name")).asTerm 

val nameLazy = instanceMirror.reflectField(nameValue) 
val nameLazyMethod = instanceMirror.reflectMethod(nameMethod) 

nameLazy.get 
    >>> null 

nameLazyMethod() 
    >>> res9: String = Fred Smith 

nameLazy.get 
    >>> res10: String = Fred Smith 
+0

你也可以嘗試'ru.typeOf [Person] .member(ru.newTermName(「name」))。asTerm.getter' – ghik 2013-05-03 17:19:50