Универсальная функция Scala... с использованием T в функции
Я немного запутался, почему приведенный ниже код не работает:
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... есть ли способ сделать то, что я пытаюсь сделать здесь?
2 ответа
Согласно документации 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)
Это на самом деле не связано с обобщениями, а скорее с последствиями и тем, как библиотеки требуют, чтобы вы определяли типы последствий и импортировали их.
Это необходимо, потому что 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
или определите себя. О том, как это сделать, вы можете прочитать в соответствующем разделе Play! документация
РЕДАКТИРОВАТЬ:
В вашем методе отсутствует неявный параметр (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
}