scala枚举值的一般类型

General type of scala Enumerations Value

我的项目中很少有像这样的 Scala 枚举:

object Tag extends Enumeration {
  type Tag = Value
  val BugFix, NewFeature, NewContent = Value

  implicit val tagFormat = EnumUtils.enumFormat(Tag)
}

其中标记格式的类型为 play.api.libs.json.Format[Tag.Value]。它可以从 JSON 解析枚举,我还使用它序列化为我保存到数据库的文本。为此每个枚举也有这个代码:

def parse(s: String) = {
  tagFormat.reads(JsString(s)) match {
    case s: JsSuccess[Tag] => s.get
    case _ => throw new ParseException(s"String of: $s is not parsable into [${getClass.getName}}]", 0)
  }
}

我正在尝试将此代码提取到实用程序函数中。我的尝试如下:

def generalParse[A](format: Format[Enumeration.Value])(s: String) = {
  format.reads(JsString(s)) match {
    case s: JsSuccess[A] => s.get
    case _ => throw new ParseException(s"String of: $s is not parsable into [${getClass.getName}}]", 0)
  }
}

然后每个枚举只需要这个代码:

def parse(s: String) = generalParse[Tag](tagFormat)

问题是我不知道如何键入 generalParse 格式参数。 Enumeration.Value 不起作用。我也试过使用 Any 但它不起作用。

通常你使用类型投影Enumeration#Value

scala> def f[A <: Enumeration] = Days.Mon match { case _: A#Value => }
f: [A <: Enumeration]=> Unit

scala> f[Days.type]

scala> f[Colors.type]

如果你想要一个有用的匹配,你需要一个外部值来比较:

scala> def f[A <: Enumeration](a: A) = (Days.Mon: Any) match { case _: a.Value => }
f: [A <: Enumeration](a: A)Unit

scala> f(Days)

scala> f(Colors)
scala.MatchError: Mon (of class scala.Enumeration$Val)
  at .f(<console>:11)
  ... 33 elided