0

有什么方法可以在 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

怎么办?在这种情况下,我试图达到一个值 Letter.B 的对象。

我在另一个帖子上看到了这个剪辑:

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

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

4

2 回答 2

1

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

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)
}
于 2013-06-14T00:34:39.603 回答
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")
于 2013-06-14T15:10:00.610 回答