【问题标题】:Creating Writes[T] for Custom Object为自定义对象创建 Writes[T]
【发布时间】:2014-02-06 19:04:17
【问题描述】:

Play for Scala 展示了如何将 JSON 转换为 Scala 对象。

case class Product(ean: Long, name: String, description: String)

    import play.api.libs.json._
    import play.api.libs.functional.syntax._

    implicit val productWrites: Writes[Product] = (
      (JsPath \ "ean").write[Long] and
      (JsPath \ "name").write[String] and
      (JsPath \ "description").write[String]
    )(unlift(Product.unapply))

然后在 REPL 中使用:

scala> val p = Product(100, "tilley hat", "Nice hat")
p: Product = Product(100,tilley hat,Nice hat)

scala> Json.toJson(p)
res1: play.api.libs.json.JsValue = {"ean":100,"name":"tilley hat",
                                             "description":"Nice hat"}

最后一行:(unlift(Product.unapply))Writes[Product] 是怎么回事?

【问题讨论】:

  • 请注意,您将获得与implicit val productWrites: Writes[Product] = Json.writes[Product] 相同的Writes

标签: json scala playframework


【解决方案1】:

Product.unapply _ 是一个函数Product => Option[(Long, String, String)]

这个表达式的结果类型:

(
  (JsPath \ "ean").write[Long] and
  (JsPath \ "name").write[String] and
  (JsPath \ "description").write[String]
)

FunctionalBuilder[OWrites]#CanBuild3[Long,String,String]。它接受T => (Long, String, String) 作为方法apply 的参数。

所以你必须将Product => Option[(Long, String, String)] 转换为Product => (Long, String, String)

方法unlift 接受T => Option[R] 并返回T => R。未提升的函数抛出 MatchError 而不是 None。它产生这样的东西:

val unlifted = (Product.unapply _) andThen { case Some(r) => r }

case 类的默认 unapply 方法永远不应返回 None,因此 case 类 unlift 是安全的。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多