Scala泛型:无法将T的实例写入HTTP响应。尝试定义一个可写的[T]
使用泛型编写以下代码时会出现编译错误 不带泛型Scala泛型:无法将T的实例写入HTTP响应。尝试定义一个可写的[T],scala,generics,playframework,Scala,Generics,Playframework,使用泛型编写以下代码时会出现编译错误 不带泛型 def getData(id: String) = Action.async { val items = getItems(id) sendResult(items) } private def sendResult(result: Future[Any]) = { result.map { items => { try { val itemStr =
def getData(id: String) = Action.async {
val items = getItems(id)
sendResult(items)
}
private def sendResult(result: Future[Any]) = {
result.map {
items => {
try {
val itemStr = items.asInstanceOf[String]
Ok(itemStr)
} catch {
case t: ClassCastException => InternalServerError(s"Casting Exception while processing output $t")
}
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
def getData(id: String) = Action.async {
val items = getItems(id)
sendResult[String](items)
}
private def sendResult[T](result: Future[Any]) = {
result.map {
items => {
try {
val itemStr = items.asInstanceOf[T]
Ok(itemStr)
} catch {
case t: ClassCastException => InternalServerError(s"Casting Exception while processing output $t")
}
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
具有通用性
def getData(id: String) = Action.async {
val items = getItems(id)
sendResult(items)
}
private def sendResult(result: Future[Any]) = {
result.map {
items => {
try {
val itemStr = items.asInstanceOf[String]
Ok(itemStr)
} catch {
case t: ClassCastException => InternalServerError(s"Casting Exception while processing output $t")
}
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
def getData(id: String) = Action.async {
val items = getItems(id)
sendResult[String](items)
}
private def sendResult[T](result: Future[Any]) = {
result.map {
items => {
try {
val itemStr = items.asInstanceOf[T]
Ok(itemStr)
} catch {
case t: ClassCastException => InternalServerError(s"Casting Exception while processing output $t")
}
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
该代码是play应用程序控件方法的一部分。第一个很好用。第二个给出了以下编译错误
无法将T的实例写入HTTP响应。尝试定义一个
可写[T][错误]正常(itemStr)[错误]
Ok(…)
正在调用Status
类上的方法apply[C](内容:C)(隐式可写:可写[C]):Result
。您需要在作用域中为可写[T]
提供一个隐式值
作为旁注,与其使用Future[Any],不如使用Future[T]并移除该类型。您还可以使用写入
进行JSON序列化
private def sendResult[T](result: Future[T])(implicit writeable: Writes[T]) = {
result.map {
items => {
Ok(Json.toJson(items))
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
将
Any
与泛型函数一起使用没有多大意义
private def sendResult[T](result: Future[Any])
// Should better be
private def sendResult[T](result: Future[T])
// ... also remove the unsafe cast
然后这个T
需要提供一个可写的实例,这样它就可以通过网络写入数组[字节]
// Either ...
private def sendResult[T: Writeable](result: Future[T])
// ... or ...
private def sendResult[T](result: Future[T])(implicit w: Writeable[T])
Play知道如何将字符串转换为HTTP响应。但是,使用泛型类型T无法让Play实现这一点。请检查,但在运行时,我提供的类型T是String.Related,不清楚您要做什么。无论项是什么
,您似乎只是想要它的字符串版本。是吗?那么隐式可写方法是如何传递给sendResult方法的呢?@konquestor应该传递给。。。含蓄地对于字符串,您不必做任何事情,因为它已经定义。如果要传递自定义结构,则必须在调用sendResult的范围内(在getData函数中,或在定义这些方法的类/对象/模块中)添加一个隐式val
。如果将Ok(items)更改为Ok(Json.toJson(items)),并且出现错误,我会看到代码再次中断“未找到类型T的Json序列化程序。请尝试为此类型实现隐式写入或格式。“如果某个东西是可写的,那么它不应该是json序列化的吗?是的。“我对你的答案投了赞成票,我不知道为什么有人对它投了反对票。”konquestor赞赏道。如果它对您有效,请选择它作为有效的公认答案!但是,如果我将Ok(items)更改为Ok(Json.toJson(items),它将再次中断,并显示“未找到类型T的Json序列化程序。请尝试实现此类型的隐式写入或格式”。Json不应序列化可写的内容?@konquestor将Json包中的隐式可写[T]
更改为写入[T]