Can';使用Scala反射无法继承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

我正在使用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] = {
    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,这似乎很奇怪。它看起来像一只虫子