Can';使用Scala反射无法继承VAL
我正在使用Scala 2.10.1,我正在尝试定义一个方法,该方法将从一个对象检索所有VAL(包括继承的VAL) 我有以下资料:Can';使用Scala反射无法继承VAL,scala,reflection,scala-2.10,Scala,Reflection,Scala 2.10,我正在使用Scala 2.10.1,我正在尝试定义一个方法,该方法将从一个对象检索所有VAL(包括继承的VAL) 我有以下资料: import scala.reflect.runtime.{universe => ru} object Reflection { val mirror = ru.runtimeMirror(this.getClass.getClassLoader) def findVals(x: Any): Iterable[String] = { va
import scala.reflect.runtime.{universe => ru}
object Reflection {
val mirror = ru.runtimeMirror(this.getClass.getClassLoader)
def findVals(x: Any): Iterable[String] = {
val theType = mirror.classSymbol(x.getClass).toType
theType.members.collect({case x if x.isTerm => x.asTerm}).filter(_.isVal).map(_.name.toString)
}
}
我正在测试这两个类:
class Base {
val x = 10
}
class Child extends Base {
val y = 20
}
调用以下代码时:
val x = new Child
val vs = Reflection.findVals(x)
println(vs)
结果是List(y)
出于某种原因,isVal
方法从Base
类返回与x
字段对应的术语的false
有人能告诉我这里有什么问题吗?我做错什么了吗?根据您应该使用isAccessor
而不是isVal
实际上,我正在使用isGetter
和setter
根据您的评论正确过滤var
s:
def findVals(x: Any): Iterable[String] = {
val theType = mirror.classSymbol(x.getClass).toType
val xtm = theType.members.collect({case x if x.isTerm => x.asTerm})
xtm.filter(m => m.isGetter && !xtm.exists(m.setter == _)).map(_.name.toString)
}
结果:
scala> class Base {
| var x = 10
| val xx = 2
| }
defined class Base
scala> class Child extends Base {
| val y = 3
| }
defined class Child
scala> val x = new Child
x: Child = Child@1c0026e
scala> val vs = Reflection.findVals(x)
vs: Iterable[String] = List(y, xx)
scala> println(vs)
List(y, xx)
根据,您应该使用isAccessor
而不是isVal
实际上,我正在使用isGetter
和setter
根据您的评论正确过滤var
s:
def findVals(x: Any): Iterable[String] = {
val theType = mirror.classSymbol(x.getClass).toType
val xtm = theType.members.collect({case x if x.isTerm => x.asTerm})
xtm.filter(m => m.isGetter && !xtm.exists(m.setter == _)).map(_.name.toString)
}
结果:
scala> class Base {
| var x = 10
| val xx = 2
| }
defined class Base
scala> class Child extends Base {
| val y = 3
| }
defined class Child
scala> val x = new Child
x: Child = Child@1c0026e
scala> val vs = Reflection.findVals(x)
vs: Iterable[String] = List(y, xx)
scala> println(vs)
List(y, xx)
因此,这是非常不雅观的,但它似乎起了作用:
import scala.reflect.runtime.{universe => ru}
object Reflection {
val mirror = ru.runtimeMirror(this.getClass.getClassLoader)
val ObjectClass = classOf[java.lang.Object];
def findVals(x: Any) : Iterable[String] = findVals( x.getClass, List.empty );
def findVals(clz: Class[_], accum : Iterable[String]): Iterable[String] = {
clz match {
case ObjectClass => accum;
case _ => {
val theType = mirror.classSymbol(clz).toType
val newVals = theType.members.collect({case x if x.isTerm => x.asTerm}).filter(_.isVal).map(_.name.toString)
findVals( clz.getSuperclass, accum ++ newVals )
}
}
}
}
然后
scala> class Base {
| val x = 10
| var z = 20
| }
defined class Base
scala> class Child extends Base {
| val y = 20
| var a = 9
| }
defined class Child
scala> val x = new Child
x: Child = Child@3093266d
scala> val vs = Reflection.findVals(x)
vs: Iterable[String] = List("y ", "x ")
scala> println(vs)
List(y , x )
看起来,至少现在,要确定val的存在,我想你只需要爬升类层次结构。。。我猜它是在寻找一个设定者来区分val和var。再一次,它不是那么可爱,而是功能性的。因此,这非常不雅观,但似乎有效:
import scala.reflect.runtime.{universe => ru}
object Reflection {
val mirror = ru.runtimeMirror(this.getClass.getClassLoader)
val ObjectClass = classOf[java.lang.Object];
def findVals(x: Any) : Iterable[String] = findVals( x.getClass, List.empty );
def findVals(clz: Class[_], accum : Iterable[String]): Iterable[String] = {
clz match {
case ObjectClass => accum;
case _ => {
val theType = mirror.classSymbol(clz).toType
val newVals = theType.members.collect({case x if x.isTerm => x.asTerm}).filter(_.isVal).map(_.name.toString)
findVals( clz.getSuperclass, accum ++ newVals )
}
}
}
}
然后
scala> class Base {
| val x = 10
| var z = 20
| }
defined class Base
scala> class Child extends Base {
| val y = 20
| var a = 9
| }
defined class Child
scala> val x = new Child
x: Child = Child@3093266d
scala> val vs = Reflection.findVals(x)
vs: Iterable[String] = List("y ", "x ")
scala> println(vs)
List(y , x )
看起来,至少现在,要确定val的存在,我想你只需要爬升类层次结构。。。我猜它是在寻找一个setter来区分val和var。同样,它不是那么可爱,而是功能性的。使用:
使用:
请注意这并不能回答我的问题哦,对不起。我误读了这个问题。请看这并不能回答我的问题。哦,对不起。我误解了这个问题。问题是这也会返回VAR。例如,如果
Base
中的x
成为一个var,它也将与x_u$eq
一起返回。是的,这样就可以了,谢谢。不过,对于继承的成员,isVal并没有返回true,这似乎很奇怪。这看起来像一个错误,问题是这也会返回VAR。例如,如果Base
中的x
成为一个var,它也将与x_u$eq
一起返回。是的,这样就可以了,谢谢。不过,对于继承的成员,isVal并没有返回true,这似乎很奇怪。它看起来像一只虫子