我将scala Enumeration类型与Play Framework的Reads and Writes结合使用。我想有一个特点:
trait EnumerationWrites[T <: Enumeration] {
def reads(jsonValue: JsValue): JsResult[T] = jsonScope match {
case JsString(s) => JsSuccess(T.withName(s)) <-- ERROR!
case _ => JsError("String value expected")
}
}
然后我会做类似
的事情object MyObject extends EnumerationTrait[T]
这不起作用 - 编译器无法在案例匹配中解析T类型。有什么问题?
答案 0 :(得分:1)
坏消息:您无法调用类型参数的方法withName
。你需要一个物体
好消息:这个对象可能是隐含的。如果您熟悉scala中类型类概念的实现,那么您已经知道了。
因此,对于Enumeration
的一般用途反序列化器,您可以使用如下函数:
implicit def enumerationReads[T <: Enumeration](implicit enum: T): Reads[enum.Value] = {
val names: Set[String] = enum.values map (_.toString)
Reads {
case JsString(s) => if (names contains s) JsSuccess(enum withName s)
else JsError(s"could not find value '$s' for $enum")
case _ => JsError("String value expected")
}
}
正如您所看到的,它要求枚举隐式可用,因此您应该为此声明枚举
implicit case object Colors extends Enumeration {
val Red, Blue = Value
}
或者为现有对象提供一些隐含值,例如
implicit val colorsEvidence = Colors