scala:定义已定义某个隐式的Type

时间:2012-08-24 03:24:15

标签: scala types playframework-2.0

我想用泛型类型T定义一个函数,其中对于T,存在某个方法的隐式实现

事实上,我正在尝试实现以下目标:

我有非常重复的代码:

def update(id: Long) = CORSAction { implicit request =>
  request.body.asJson.map { json =>
    json.asOpt[Wine].map { wine =>
      wine.copy(id=Id(id)).update.fold(
        errors => JsonBadRequest(errors),
        wine => Ok(toJson(wine).toString)
      )
    }.getOrElse       (JsonBadRequest("Invalid Wine entity"))
  }.getOrElse         (JsonBadRequest("Expecting JSON data"))
}

因此,检查它是否是一个有效的json,然后解析它,这是一个非常常见的任务,我想封装在一个函数中。

对于wine类型,我定义了一个隐式JsonWineFormatter,它实现了一个write和reads方法,用于从json解析并渲染为json一个wine对象

object WineFormatter {

  implicit object JsonWineFormatter extends Format[Wine] {

    def writes(o: Wine): JsValue = {
      toJson( Map(
        "id"          -> toJson(o.id),
    [...]

    def reads(j: JsValue): Wine = {
      Wine(
        id = (j \ "id").as[Option[Pk[Long]]] 
    [...]

所以我试图定义这样的通用方法:

def parse[T](implicit request: Request[AnyContent]): Option[T] = {
  request.body.asJson.map { json =>
    json.asOpt[T].map { entity =>
      entity
    }
  }
}

但是我得到了followgin错误:

找不到类型T的Json反序列化器。尝试为此类型实现隐式读取或格式。

我需要指定泛型类型T需要和隐式读取...

你知道怎么做吗?

-

编辑:我尝试了以下内容:

import play.api.libs.json.JsValue
type EntityWithJsonFormatter[T] = T {def reads(j: JsValue): T}

def parse[T: EntityWithJsonFormatter](request: Request[AnyContent]): Option[T] = {
  request.body.asJson.map { json =>
    json.asOpt[T].map { entity =>
      entity
    }
  }
}

但显然,并不是那个用来实现读取的东西,而是应该有一个实现它的隐式对象。我不知道如何在类型中指定...

1 个答案:

答案 0 :(得分:4)

JsValue文档定义asOpt因此:

def asOpt [T] (implicit fjs: Reads[T]): Option[T] 

所以如果你import play.api.libs.json.Reads那么

def parse[T: Reads]( ...

应该这样做。