Scala类型"查看" - 无法访问伴随对象中的方法

时间:2015-10-18 16:40:49

标签: scala playframework typeclass traits

我将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类型。有什么问题?

1 个答案:

答案 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