在Scala中实现Pk写入的通用方法

在Scala中实现Pk写入的通用方法,scala,generics,playframework-2.0,Scala,Generics,Playframework 2.0,我试图在Play 2.1中编写一种处理将Pk类写入JSON的通用方法,因为我认为为您使用的每个Pk类型编写一个单独的类是浪费的。以下是我目前掌握的情况: implicit def pkWrites[E] = new Writes[Pk[E]] { def writes(pk: Pk[E]): JsValue = Json.toJson(pk.get) } …我在这样的代码中使用它: Json.toJson(Id(42L)) 现在,这类方法可行(Scala找到了),但我得到的错误如下:

我试图在Play 2.1中编写一种处理将
Pk
类写入JSON的通用方法,因为我认为为您使用的每个
Pk
类型编写一个单独的类是浪费的。以下是我目前掌握的情况:

implicit def pkWrites[E] = new Writes[Pk[E]] {
    def writes(pk: Pk[E]): JsValue = Json.toJson(pk.get)
}
…我在这样的代码中使用它:

Json.toJson(Id(42L))
现在,这类方法可行(Scala找到了),但我得到的错误如下:

No Json deserializer found for type E. 
Try to implement an implicit Writes or Format for this type.

其中类型
E
Long
(因此,具有反序列化器)。我能告诉你
Json.toJson
什么类型
E
吗?

你需要做的唯一一件事就是确保范围内有
E
类型的反序列化程序,因为现在你不能确定你使用的每种类型都是可写的。你可以试试:

class Value[A](value: A){
  def get[A] = value
}

implicit def valueWrites[E](implicit longWrites: Writes[E]) = new Writes[Value[E]]{
    def writes(value: Value[E]): JsValue = Json.toJson(value.get)
}

Json.toJson(new Value(5L))
您可以将隐式方法缩短为:

implicit def valueToJson[E: Writes] = new Writes[Value[E]]{
    def writes(value: Value[E]): JsValue = Json.toJson(value.get)
}
编辑:

上述两种方法完全相同,这意味着该方法需要隐式值,在您的例子中,
Pk[Long]
,因此该方法知道如何反序列化数字。换句话说,
E:Writes
告诉方法:搜索
Writes[E]
类型的隐式值

编辑2:


Json.toJson(1)
之所以有效,是因为作用域中有
写入[Int]
。同样的工作方式是
valueWrites[Int]
,作用域中有
Writes[Int]
,所以方法可以使用
Writes[Int]
来反序列化字段
value
,从而反序列化整个类。

好的,所以我所做的就是将
E:Writes
添加到
pkWrites
类型参数中,它就工作了。。。类型参数中的
是什么意思?我对Scala非常陌生。所以
E:Writes
是“确保
E
可以隐式转换为
Writes
”的缩写。它是“范围内有写[E]或写[Long]的简写”