我有一些代码通过使用spray.json将Stream
个案例类转换为json表示来传输响应。这适用于单个案例类,但我想将其泛化。
所以我从这样的案例类开始:
import spray.json._
import spray.json.DefaultJsonProtocol._
case class Item(foo: String, bar: Int)
case class Report(baz: String, stream: Stream[Item])
object Protocol { implicit val ItemFormat = jsonFormat2(Item) }
在我的报告流媒体方法中,我有这样的代码(高度简化):
def streamReport(...) {
import Protocol._
val handler: PartialFunction[Try[Any], String] = {
case Success(Report(_, stream)) =>
stream.head.toJson.compactPrint
}
}
我想要做的是将Report
通用化以支持超过项目:
case class Report[T](baz: String, stream: Stream[T])
但是现在,streamReport
方法现在无法在类型JsonWriter
的范围内找到Any
。
如果我添加一个绑定到streamReport
的上下文的类型参数,我可以做一些接近我想要的事情,并直接传入Report
:
def jsonStream[T : JsonWriter](report: Report[T]): String =
implicitly[JsonWriter[T]].write(report.stream.head).compactPrint
但是,我无法弄清楚如何使用PartialFunction
。以下内容无法编译(由于部分函数的签名与上述不同,因此无法完全拟合):
def handler[T : JsonWriter](): PartialFunction[T, String] = {
case Success(Report(_, stream)) =>
implicitly[JsonWriter[T]].write(report.stream.head).compactPrint
}
我不确定它出了什么问题。是否与类型擦除有关,或者在我的部分函数中使用Try[Any]
作为参数类型的问题?如何获取流所需元素类型所需的隐式JsonWriter?
答案 0 :(得分:0)
我的猜测是Any
不是问题,问题是在case Success(Report(_, stream))
的定义现在为Report
之后尝试匹配Report[T]
。
另外,为了找到正确的隐式转换,编译器需要理解所涉及的类型(在编译时)。尝试使用这样的东西:
def streamReport[T](...) {
import Protocol._
val handler: PartialFunction[Try[Any], String] = {
case Success(Report[T](_, stream)) =>
stream.head.toJson.compactPrint
}
}
这样,编译器就会知道匹配的内容,并可以推断出正确的类型。