Scala 2.10带来了除了提供JVM(或者我猜CLR)之外的反射.
我们还有什么特别值得期待的,它将如何在平台上得到改善?
例如,是否会有一个类反映语言在字段和访问器方法之间的可转换性,以便我可以迭代对象的属性?
我需要由字符串名称定义的对象(或"单例对象"或"伴随对象"......除了类之外的任何东西).换句话说,如果我有:
package myPackage
object myObject
Run Code Online (Sandbox Code Playgroud)
...那么有这样的事情:
GetSingletonObjectByName("myPackage.myObject") match {
case instance: myPackage.myObject => "instance is what I wanted"
}
Run Code Online (Sandbox Code Playgroud) 在过去,当Invocation(一个实验性实用程序)是标准库的一部分时,可以"动态"调用方法,如下所示:
"Hello!" o 'substring(0, 4) // to get Any back
"Hello!" oo 'substring(0, 4) // for an automatic unsafe cast to expected type
Run Code Online (Sandbox Code Playgroud)
如何使用新的Scala反射API执行此操作?
我有这样的课:
trait ThirdParty { def invoke = println("right") }
trait WeatherIcon { def invoke = println("wrong") }
class MyClass {
object objA extends ThirdParty
object objB extends WeatherIcon
}
Run Code Online (Sandbox Code Playgroud)
如何使用Scala反射API迭代包含的对象并调用方法(如果它是ThirdParty类的实例)?
我想获得一个scala对象的内部对象列表.示例代码:
object Outer {
val v = "-"
def d = "-"
object O1
object O2
}
object Main {
def main(args: Array[String]) {
Outer.getClass.getDeclaredMethods.map(_.getName) foreach println // prints d and v
// Outer.getClass.get ... Objects???
}
}
Run Code Online (Sandbox Code Playgroud)
我可以找到v和d,但我怎样才能找到O1和O2?
我使用新的Scala反射API(来自https://gist.github.com/xeno-by/4985929的代码)实现了Get companion对象实例中提到的代码.
object Reflection {
def getCompanionObject(caseclassinstance:Product):Any = {
import scala.reflect.runtime.{currentMirror => cm}
val classSymbol = cm.classSymbol(caseclassinstance.getClass)
val moduleSymbol = classSymbol.companionSymbol.asModule
val moduleMirror = cm.reflectModule(moduleSymbol)
moduleMirror.instance
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于任何标准类的案例类.不幸的是在项目的某些类中我得到一个异常:scala.ScalaReflectionException: object Tensor is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror异常非常清楚,所以我尝试按如下方式更改代码:
object Reflection {
def getCompanionObject(caseclassinstance:Product):Any = {
import scala.reflect.runtime.{currentMirror => cm}
val classSymbol = cm.classSymbol(caseclassinstance.getClass)
val moduleSymbol = classSymbol.companionSymbol.asModule
val instanceMirror = cm.reflect(caseclassinstance)
val moduleMirror = instanceMirror.reflectModule(moduleSymbol)
moduleMirror.instance …Run Code Online (Sandbox Code Playgroud) 关注这个问题,我试图弄清楚如何在一个对象上调用一个方法.相关定义是:
trait ThirdParty { def invoke = println("right") }
trait WeatherIcon { def invoke = println("wrong") }
class MyClass {
object objA extends ThirdParty
object objB extends WeatherIcon
}
Run Code Online (Sandbox Code Playgroud)
我有一个Symbol为objA这样的:
import reflect.runtime.universe._
val stuff = typeOf[MyClass].members.filter(_.isValue).filter(_.typeSignature <:< typeOf[ThirdParty])
Run Code Online (Sandbox Code Playgroud)
返回一个Iterable元素,所以让我们说:
val objASymbol = stuff.head.asModuleSymbol
Run Code Online (Sandbox Code Playgroud)
然后我根据这个问题尝试了这个:
val mirror = runtimeMirror(getClass.getClassLoader)
mirror.reflectModule(objASymbol)
Run Code Online (Sandbox Code Playgroud)
这导致了主题上引用的错误消息:
java.lang.Error: this is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror
at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectModule(JavaMirrors.scala:118)
at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectModule(JavaMirrors.scala:60)
Run Code Online (Sandbox Code Playgroud)
问题是我无法弄清楚这条错误信息告诉我要做什么!