Scala 通用函数...在函数中使用 T
Scala Generic Function... using T in Function
我有点困惑为什么下面的代码不起作用:
implicit val connectReads: Reads[ConnectCommand] = (
(JsPath \ "uuid").read[String]
)(ConnectCommand.apply _)
private def generateMessage[T](json: JsValue) = json.validate[T] match {
case s: JsSuccess[T] => s.asOpt
case e: JsError => None
}
函数调用如下:
generateMessage[ConnectCommand](json)
我收到以下错误:
Error:(59, 64) No Json deserializer found for type T. Try to implement an implicit Reads or Format for this type.
private def generateMessage[T](json: JsValue) = json.validate[T] match {
^
Error:(59, 64) not enough arguments for method validate: (implicit rds: play.api.libs.json.Reads[T])play.api.libs.json.JsResult[T].
Unspecified value parameter rds.
private def generateMessage[T](json: JsValue) = json.validate[T] match {
^
我对 Scala 泛型还很陌生...有什么方法可以做我在这里想做的事情吗?
这实际上与泛型无关,而是与隐式相关,以及库如何要求您定义隐式类型并导入它们。
这是必需的,因为 validate
函数不知道您的 JsValue
的格式,因此需要 implicit scope
提供一个。然后它使用格式来验证它。起初它令人困惑,但最终会更好,因为当需要 JSON 格式时,您不必为每个方法调用显式提供格式。
还有这两行在错误消息中泄露了它:
Try to implement an implicit Reads or Format for this type.
not enough arguments for method validate: (implicit rds: play.api.libs.json.Reads[T])
我们看到您需要导入隐式 Format
/Reads
或自己定义一个。您可以阅读有关如何执行此操作的信息 in the relevant section of the Play! documentation。
编辑:
您的方法缺少隐式参数 (implicit reads: Reads[T])
以将其传递给 validate
函数:
private def generateMessage[T](json: JsValue)(implicit reads: Reads[T]) = json.validate[T] match {
case s: JsSuccess[T] => s.asOpt
case e: JsError => None
}
根据文档,JsValue.validate
需要隐式 Reads
才能使您的类型可用:
def validate[T](implicit rds: Reads[T]): JsResult[T]
假设您在调用 generateMessage
的地方可以使用它,您必须将它传递到 generateMessage
,这样 validate
也会看到它:
private def generateMessage[T](json: JsValue)(implicit rds: Reads[T])
或更短的形式:
private def generateMessage[T : Reads](json: JsValue)
我有点困惑为什么下面的代码不起作用:
implicit val connectReads: Reads[ConnectCommand] = (
(JsPath \ "uuid").read[String]
)(ConnectCommand.apply _)
private def generateMessage[T](json: JsValue) = json.validate[T] match {
case s: JsSuccess[T] => s.asOpt
case e: JsError => None
}
函数调用如下:
generateMessage[ConnectCommand](json)
我收到以下错误:
Error:(59, 64) No Json deserializer found for type T. Try to implement an implicit Reads or Format for this type.
private def generateMessage[T](json: JsValue) = json.validate[T] match {
^
Error:(59, 64) not enough arguments for method validate: (implicit rds: play.api.libs.json.Reads[T])play.api.libs.json.JsResult[T].
Unspecified value parameter rds.
private def generateMessage[T](json: JsValue) = json.validate[T] match {
^
我对 Scala 泛型还很陌生...有什么方法可以做我在这里想做的事情吗?
这实际上与泛型无关,而是与隐式相关,以及库如何要求您定义隐式类型并导入它们。
这是必需的,因为 validate
函数不知道您的 JsValue
的格式,因此需要 implicit scope
提供一个。然后它使用格式来验证它。起初它令人困惑,但最终会更好,因为当需要 JSON 格式时,您不必为每个方法调用显式提供格式。
还有这两行在错误消息中泄露了它:
Try to implement an implicit Reads or Format for this type.
not enough arguments for method validate: (implicit rds: play.api.libs.json.Reads[T])
我们看到您需要导入隐式 Format
/Reads
或自己定义一个。您可以阅读有关如何执行此操作的信息 in the relevant section of the Play! documentation。
编辑:
您的方法缺少隐式参数 (implicit reads: Reads[T])
以将其传递给 validate
函数:
private def generateMessage[T](json: JsValue)(implicit reads: Reads[T]) = json.validate[T] match {
case s: JsSuccess[T] => s.asOpt
case e: JsError => None
}
根据文档,JsValue.validate
需要隐式 Reads
才能使您的类型可用:
def validate[T](implicit rds: Reads[T]): JsResult[T]
假设您在调用 generateMessage
的地方可以使用它,您必须将它传递到 generateMessage
,这样 validate
也会看到它:
private def generateMessage[T](json: JsValue)(implicit rds: Reads[T])
或更短的形式:
private def generateMessage[T : Reads](json: JsValue)