Scala枚举的动态实例化

时间:2013-06-14 00:09:48

标签: scala reflection enumeration

有没有办法动态实例化Scala中的Enumeration#Value?

到目前为止,我有:

object Letter extends Enumeration {
    val A,B,C = Value
}

// fieldType is of type Universe.Type for the field in my case class, which happens to
// be of type Letter.Value

val ftype = fieldType.typeSymbol.name.toString
val enumVal = "B"  // a valid Enumeration.Value
val erasedEnumType = fieldType.asInstanceOf[TypeRef]  // Letter

现在怎样?在这种情况下,我试图找到一个有价值的物品.B。

我在另一篇帖子中看到了这个片段:

def create[T <: Enum[T]](clazz: Class[T], input: String): T = Enum.valueOf(clazz, input)

我无法完成这项工作,因为我在编译时没有“T”(我在运行时从输入字符串解析这个值)。

2 个答案:

答案 0 :(得分:0)

你的意思是检索而不是实例化?

scala> object Letter extends Enumeration {
     |     val A,B,C = Value
     | }
defined module Letter

scala> Letter withName "B"
res0: Letter.Value = B

而不是creating another value

更新:

package reflectenum

import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror=>cm}
import scala.reflect.NameTransformer._

object Letters extends Enumeration {
  val A,B,C = Value
}

object Test extends App {
  val claas = cm.classLoader loadClass "reflectenum.Letters$"
  Console println s"$claas"
  val enum  = claas.getField(MODULE_INSTANCE_NAME).get(null).asInstanceOf[Enumeration]
  Console println s"$enum"
  Console println s"${enum withName "B"}"

  // given some element of the enumeration
  val v = enum withName "B"
  val im = cm reflect v
  val outerName = newTermName("scala$Enumeration$$outerEnum")
  val outer = typeOf[enum.Value] member outerName
  val f = im reflectField outer.asTerm.accessed.asTerm
  assert(enum == f.get)
}

答案 1 :(得分:0)

这有效:

val foo = Class.forName("reflectnum.Letter$") //← note extra $
val anObj = foo.getField("MODULE$").get(foo)
val meth = anObj.getClass.getMethod("withName",classOf[String])
val z = meth.invoke(anObj,"B")