2013-05-03 31 views
8

Sử dụng thử nghiệm Scala 2.10 phản ánh, khi tôi cố gắng gọi FieldMirror.get() trên một trường là một val lười biếng, nó trả về null. Có cách nào để đánh giá val lười biếng bằng cách sử dụng sự phản ánh? Hàm get() không còn trả về null sau đó.Làm thế nào tôi có thể đánh giá một val lười biếng bằng cách sử dụng sự phản ánh?

Hãy xem xét ví dụ sau:

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

buộc đánh giá biểu thức lười biếng đó. tôi không biết chi tiết cụ thể trong scala. –

+0

Tại thời điểm này, tôi chỉ có một tham chiếu đến val lười biếng - một FieldMirror - vì vậy tôi không thể đơn giản đánh giá nó. Hàm get() trả về biểu thức và sau đó tôi có thể dễ dàng đánh giá nó. – vertexshader

Trả lời

6

tôi phát hiện ra các giải pháp. Có một phương pháp ẩn được tạo:

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

Bạn cũng có thể thử 'ru.typeOf [Person] .member (ru.newTermName (" name ")). AsTerm.getter' – ghik

Các vấn đề liên quan