Scala 无法使用json反序列化泛型集合

Scala 无法使用json反序列化泛型集合,scala,spray,spray-json,Scala,Spray,Spray Json,我正在尝试将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]] } } pri

我正在尝试将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]]
  }
}
private def loadElements[T: JsonReader]: Set[T]
private def loadElements[T](implicit p: JsonReader[T]): Set[T]
def collectionType1: Set[Type1] = {
  import Type1JsonProtocol.*
  loadElements[Type1]
}
我还定义了以下内容(我对“Type2”有完全相同的定义,case类看起来不同):

编译代码时,出现以下错误:

Error:(25, 29) Cannot find JsonReader or JsonFormat type class for Set[T]
    val res = json.convertTo[Set[T]]
                            ^
以及:

我显然错过了一些东西,但我有一种感觉,这是一件小事。有人有什么线索吗


谢谢

下面是JsValue的convertTo函数的定义

def convertTo[T](implicit evidence$1 : spray.json.JsonReader[T])
如您所见,您应该为类型T提供JsonReader作为implicit参数

您无法确定什么是t的真正类型及其JsonReader,因此只需再次像这样使用隐式参数:

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]]
  }
}
private def loadElements[T: JsonReader]: Set[T]
private def loadElements[T](implicit p: JsonReader[T]): Set[T]
def collectionType1: Set[Type1] = {
  import Type1JsonProtocol.*
  loadElements[Type1]
}
如果您不熟悉上述样式,可以按如下方式展开代码:

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]]
  }
}
private def loadElements[T: JsonReader]: Set[T]
private def loadElements[T](implicit p: JsonReader[T]): Set[T]
def collectionType1: Set[Type1] = {
  import Type1JsonProtocol.*
  loadElements[Type1]
}
如果要调用此函数,应提供具体类型,而不是类型T及其JsonReader,如下所示:

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]]
  }
}
private def loadElements[T: JsonReader]: Set[T]
private def loadElements[T](implicit p: JsonReader[T]): Set[T]
def collectionType1: Set[Type1] = {
  import Type1JsonProtocol.*
  loadElements[Type1]
}

通过这种技术,您可以在编译时而不是运行时检测错误的反序列化问题。

这只是一个愚蠢的错误。只需将隐式参数添加到“loadElements”函数中。另请注意:
DefaultJsonProtocol
已经为任何具有隐式格式的T实现了
RootJsonFormat[Set[T]]
。它还包括Scala标准库中所有不可变集合的实现。