我试图将json字符串反序列化为泛型集合。
我的代码看起来像这样:
class MyClass(json: String) {
def collectionType1: Set[Type1] = loadElements[Type1]
def collectionType2: Set[Type2] = ???
private def loadElements[T]: Set[T] = {
json.parseJson.convertTo[Set[T]]
}
}
我也有以下定义(我对' Type2'有完全相同的定义,案例类看起来不同):
case class Type1(p1: String, p2: String)
object Type1JsonProtocol extends DefaultJsonProtocol {
private implicit val collectionType1Format = jsonFormat2(Type1)
implicit object Type1SetJsonReader extends JsonReader[Set[Type1]] {
override def read(json: JsValue): Set[Type1] = json match {
case JsArray(elements) => elements.map(_.convertTo[Type1]) toSet
case x => deserializationError("Expected Collection as JsArray, but got " + x)
}
}
}
编译代码时,出现以下错误:
Error:(25, 29) Cannot find JsonReader or JsonFormat type class for Set[T]
val res = json.convertTo[Set[T]]
^
和
Error:(25, 29) not enough arguments for method convertTo: (implicit evidence$1: spray.json.JsonReader[Set[T]])Set[T].
Unspecified value parameter evidence$1.
val res = json.convertTo[Set[T]]
^
我显然错过了一些东西,但感觉它有点小。有没有人有任何线索?
谢谢!
答案 0 :(得分:2)
以下是JsValue的convertTo函数的定义。
def convertTo[T](implicit evidence$1 : spray.json.JsonReader[T])
如您所见,您应该为类型T提供JsonReader作为impilicit参数。
你无法确定什么是真实类型的T及其JsonReader,所以只需再次使用隐式参数:
private def loadElements[T: JsonReader]: Set[T]
如果您不熟悉上述样式,可以像这样扩展代码:
private def loadElements[T](implicit p: JsonReader[T]): Set[T]
如果要调用此函数,则应提供具体类型而不是类型T及其JsonReader,如下所示:
def collectionType1: Set[Type1] = {
import Type1JsonProtocol.*
loadElements[Type1]
}
您可以通过此技术在编译时检测错误的de / serialization问题,而不是运行时。