Play Framework 2.2.1 Json Combinators - 读取和写入编译错误

时间:2014-01-01 06:32:56

标签: scala playframework playframework-2.0 playframework-2.2

尝试从http://www.playframework.com/documentation/2.2.x/ScalaJsonCombinators运行Json读取和写入的Json Combinator示例:

def test = Action {

case class Creature(name: String,isDead: Boolean,weight: Float, email: String, favorites: (String, Int), friends: List[Creature] = Nil, social: Option[String] = None)
import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val creatureWrites: Writes[Creature] = (
  (__ \ "name").write[String] and
    (__ \ "isDead").write[Boolean] and
    (__ \ "weight").write[Float] and
    (__ \ "email").write[String] and
    (__ \ "favorites").write(
      (__ \ "string").write[String] and
        (__ \ "number").write[Int]
        tupled
    ) and
    (__ \ "friends").lazyWrite(Writes.traversableWrites[Creature](creatureWrites)) and
    (__ \ "social").write[Option[String]]
  )(unlift(Creature.unapply))

val gizmo = Creature("gremlins", false, 1.0F, "gizmo@midnight.com", ("alpha", 85), List(), Some("@gizmo"))
val gizmojs = Json.toJson(gizmo)

Ok(gizmojs toString)
}

我收到以下编译错误:

[error] ....:forward reference extends over definition of value creatureWrites
[error] (__ \ "friends").lazyWrite(Writes.traversableWrites[Creature](creatureWrites)) 

ReadsFormat存在类似的问题。

请帮忙。

2 个答案:

答案 0 :(得分:3)

  

那是因为您将隐式值定义为本地成员。类和对象允许前向引用,而本地块不允许

     

因此,只需将隐式读写定义为类成员,而不是本地

看看我的测试

规范:

import play.api.libs.json._
import play.api.libs.functional.syntax._
import org.specs2.mutable.Specification

case class Creature(
  name: String,
  isDead: Boolean,
  weight: Float,
  email: String,
  favorites: (String, Int),
  friends: List[Creature] = Nil,
  social: Option[String] = None)

class FooSpec extends Specification {
  implicit val creatureWrites: Writes[Creature] = (
    (__ \ "name").write[String] and
      (__ \ "isDead").write[Boolean] and
      (__ \ "weight").write[Float] and
      (__ \ "email").write[String] and
      (__ \ "favorites").write(
        (__ \ "string").write[String] and
          (__ \ "number").write[Int]
          tupled
      ) and
      (__ \ "friends").lazyWrite(Writes.traversableWrites[Creature](creatureWrites)) and
      (__ \ "social").write[Option[String]]
  )(unlift(Creature.unapply))
  implicit val favouriteReads: Reads[(String, Int)] =
    (__ \ "string").read[String]and
      (__ \ "number").read[Int] tupled
  implicit val creatureReads = Json.reads[Creature]

  val gizmo = Creature("gremlins", false, 1.0F, "gizmo@midnight.com", ("alpha", 85), List(), Some("@gizmo"))
  val gizmojs = Json.toJson(gizmo)
  "writes" should {
    "write scala value as string" in {
      Json.parse(gizmojs.toString).as[Creature] must be_==(gizmo)
    }
  }
}

结果:

[success] Total time: 10 s, completed Jan 1, 2014 11:25:25 PM
[ops-ui] $ testOnly FooSpec
[info] FooSpec
[info] writes should
[info] + write scala value as string
[info] Total for specification FooSpec
[info] Finished in 1 second, 813 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 6 s, completed Jan 1, 2014 11:25:45 PM

您可以轻松定义读/写

implicit val favouriteWrites =
    (__ \ "string").write[String] and
      (__ \ "number").write[Int] tupled
  implicit val creatureWrites: Writes[Creature] = Json.writes[Creature]

  implicit val favouriteReads: Reads[(String, Int)] =
    (__ \ "string").read[String]and
      (__ \ "number").read[Int] tupled
  implicit val creatureReads = Json.reads[Creature]

答案 1 :(得分:1)

你是完全正确的,它没有记录的那样。我认为Play的JSON组合器仍然处于不稳定的状态,因此文档可能会受到影响。

快速修复:将creatureWrites更改为def,因此允许“转发引用”(这是一个递归函数调用):

implicit def creatureWrites: Writes[Creature] = (
   ...
)