【问题标题】:How to use Enum.valueOf from Scala?如何使用 Scala 中的 Enum.valueOf?
【发布时间】:2011-05-19 22:03:41
【问题描述】:

我需要从给定 Enum 的 Class 实例的字符串中获取 Java 枚举值。我尝试了如下代码,但出现“未绑定通配符类型”编译错误。似乎,我需要对存在类型做一些事情,forSome {} 或其他东西,但我不知道如何正确地做。

val paramClass = method.getParameterTypes()(0)
val value = paramClass match {
  case _ if classOf[Enum[_]].isAssignableFrom(paramClass) => Enum.valueOf[_ <: Enum[_]](paramClass.asInstanceOf[Class[_ <: Enum[_]]], "MYENUM")

【问题讨论】:

    标签: java scala enums existential-type


    【解决方案1】:

    嗯,艰难的一个。我有一个可行的解决方案,但我觉得它很难看。我会对任何更优雅的方法感兴趣!

    def enumValueOf[T <: Enum[T]](cls: Class[_], stringValue: String): Enum[_] =
      Enum.valueOf(cls.asInstanceOf[Class[T]], stringValue).asInstanceOf[Enum[_]]
    
    val value = paramClass match {
      case _ if classOf[Enum[_]].isAssignableFrom(paramClass) => enumValueOf(paramClass, "MYENUM")
      case _ => // other cases
    }
    

    认为我们需要这种复杂性的原因......

    我们需要编译器相信我们拥有的Class[_] 实际上是一个Class[T &lt;: Enum[T]](因此,当然,需要初步测试这确实是一个Java 枚举——就像在你的代码中所做的那样——是必要的)。所以我们将cls 转换为Class[T],其中T 被编译器推断为&lt;: Enum[T]。但是编译器还是要找到一个合适的T,这里默认为Nothing。因此,就编译器而言,cls.asInstanceOf[Class[T]]Class[Nothing]。这暂时可以,因为它可以用来调用Enum.valueOf——问题是valueOf 的推断返回类型自然也是Nothing。这里有一个问题,因为当我们尝试实际使用Nothing 类型的实例时,编译器会插入一个异常。所以,我们最终将valueOf 的返回值转换为Enum[_]

    诀窍是始终让编译器将类型参数推断为enumValueOf,并且永远不要尝试自己指定它(因为我们不应该知道它)——从而提取对Enum.valueOf的调用在另一种方法中,让编译器有机会绑定T &lt;: Enum[T]

    正如我所说,我对这个解决方案不太满意,它看起来比应该的要复杂得多……

    更新:我稍微简化了代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-28
      • 2021-01-17
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多