将值列表扩展到个案

Expand list of values into cases

这是我的资料:

sealed abstract class Codes(list: List[String])
object UVWCodes extends Codes(List("U", "V", "W"))
object XYZCodes extends Codes(List("X", "Y", "Z"))

我想使用宏将列出的值扩展为:

parse(str: String): Codes = str match {
  case "U" | "V" | "W" => UVWCodes
  case "X" | "Y" | "Z" => XYZCodes
}

由于 Codes 是一个密封的 class,因此可以获得其子 class 的列表。但是,如何提取代码文字列表("U"、"V" 等)?

写的时候

sealed abstract class Codes(list: List[String])

list 只是一个构造函数参数,如果不使用它会丢失。如果您使用关键字 val 作为前缀,它将变为不可变的 属性 因此您可以访问外部

sealed abstract class Codes(val list: List[String])

UVWCodes.list // Valid code

借助@Edmondo1984 的决定性贡献和其他地方的片段,这里有一个完全编码的解决方案:

import scala.reflect.runtime.universe._

sealed abstract class Codes(val list: List[String])
object UVWCodes extends Codes(List("U", "V", "W"))
object XYZCodes extends Codes(List("X", "Y", "Z"))


object FindObjectsByReflection {
  def main(args: Array[String]) = {
    val c = typeOf[Codes].typeSymbol.asClass.knownDirectSubclasses
    c.foreach { x =>
      val d = getObjectInstance(x.fullName).asInstanceOf[Codes]
      println(d.list)
    }
  }
  def getObjectInstance(clsName: String): AnyRef = {
    val mirror = runtimeMirror(getClass.getClassLoader)
    val module = mirror.staticModule(clsName)
    mirror.reflectModule(module).instance.asInstanceOf[AnyRef]
  }

}