有没有办法动态实例化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”(我在运行时从输入字符串解析这个值)。
答案 0 :(得分:0)
你的意思是检索而不是实例化?
scala> object Letter extends Enumeration {
| val A,B,C = Value
| }
defined module Letter
scala> Letter withName "B"
res0: Letter.Value = B
更新:
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")