【问题标题】:scala: reflection on an inner class of abstract typescala:对抽象类型的内部类的反思
【发布时间】:2015-03-22 20:21:37
【问题描述】:

我想在特征中反映抽象类型的内部类。像这样的:

import scala.reflect.runtime.{ universe => ru }
import scala.reflect.ClassTag
import scala.reflect.api.JavaUniverse
import scala.collection.mutable.HashMap


trait SimElement {
    type Probe
    var probe: Probe

    def reflectProbe(implicit ev1: scala.reflect.runtime.universe.TypeTag[Probe]) {
    val runtimeMirror: ru.type#Mirror = ru.runtimeMirror(this.probe.getClass.getClassLoader)
    val instanceMirror = runtimeMirror.reflect(this.probe.getClass())


    val fieldTerm: ru.type#TermName = ru.TermName("name")
    println(fieldTerm.toString())
    val fieldSymbol = ru.typeOf[Probe].decl(fieldTerm)
    println(fieldSymbol.toString())
    }


}


class WorldProbe {
    var population: Long = 8000000000L
}

class World extends SimElement {
  type Probe = WorldProbe
  var probe: Probe = new WorldProbe
}


class CountryProbe {
    // to be set for every country
    var population: Int = 0

    // to be set for every country
    var name: String = ""
}

class Country extends SimElement {
    type Probe = CountryProbe
    var probe: Probe = new CountryProbe
}

// ...


val elements: List[SimElement] = List(new World, new Country)

var countries: List[SimElement] = List()
var c1: Country = new Country
c1.probe.name = "Germany"
c1.probe.population = 81000000

var c2: Country = new Country
c2.probe.name = "Netherlands"
c2.probe.population = 16000000

countries = countries.+:(c1)
countries = countries.+:(c2)

elements.foreach { (s: SimElement) => s.reflectProbe }
countries.foreach { (s: SimElement) => s.reflectProbe }

这可以编译,但不能按预期工作,它会打印: 姓名 姓名 姓名 姓名

我认为我没有在这里找到“正确”的对象,但是,进行了相当多的研究并没有找到答案。有什么帮助吗?

谢谢!

【问题讨论】:

  • 抽象类型的内部类是什么意思?

标签: scala reflection inner-classes abstract-type


【解决方案1】:

找到以下解决方案,该解决方案基于反射类型可以显式存储在类中的事实:

trait SimElement {
    type Probe
    var probe: Probe
    val probeTypeTag: ru.TypeTag[Probe]
    val probeClassTag: scala.reflect.ClassTag[Probe]
    val typeSave: reflect.runtime.universe.Type
    val typeSaveProbe: reflect.runtime.universe.Type

  def reflectTest (implicit ev: scala.reflect.ClassTag[Probe] = probeClassTag) {
        val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader)
        val im2 = runtimeMirror.reflect(this.probe)
        val fieldX2 = typeSaveProbe.declaration(ru.newTermName("name")).asTerm.accessed.asTerm
        val fmX2 = im2.reflectField(fieldX2)
        val x4= fmX2.get.asInstanceOf[String]
        println("reflection result: " + x4)
    }
}

class WorldProbe {
    var population: Long = 8000000000L
}

class World extends SimElement { 
    type Probe = WorldProbe
    var probe: Probe = new WorldProbe
    val probeTypeTag: ru.TypeTag[WorldProbe] = ru.typeTag[WorldProbe]
    val probeClassTag: scala.reflect.ClassTag[WorldProbe] = scala.reflect.classTag[WorldProbe]
    val typeSave = ru.typeOf[World]
    val typeSaveProbe = ru.typeOf[WorldProbe]
}


class CountryProbe {
    // to be set for every country
    var population: Int = 0

    // to be set for every country
    var name: String = ""
}

class Country extends SimElement {
    type Probe = CountryProbe
    var probe: Probe = new CountryProbe
    val probeTypeTag: ru.TypeTag[CountryProbe] = ru.typeTag[CountryProbe]
    val probeClassTag: scala.reflect.ClassTag[CountryProbe] = scala.reflect.classTag[CountryProbe]
    val typeSave = ru.typeOf[Country]
    val typeSaveProbe = ru.typeOf[CountryProbe]
}

// ...


val features: List[SimElement] = List(new World, new Country)

var countries: List[SimElement] = List()
var c1: Country = new Country
c1.probe.name = "Germany"
c1.probe.population = 81000000

var c2: Country = new Country
c2.probe.name = "Netherlands"
c2.probe.population = 16000000

countries = countries.+:(c1)
countries = countries.+:(c2)

countries.foreach { (s: SimElement) => s.reflectTest }

欢迎任何 cmets 或更好的建议。

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    相关资源
    最近更新 更多