Воспроизвести JSON Записывает, как он получает значения поля в правильное поле

Я пытался понять Writes[T] на более глубоком уровне, чем просто принять, что он работает, как я знаю. Что меня смущает, так это то, что после неприменения и отмены T я понимаю, что вы закончили с кортежем значений. Как сопоставить эти значения с нужным местом, если они все одного типа, например Doubles, как показано ниже? Я задавался вопросом, связано ли это с порядком комбинаторов, но локальные эксперименты, кажется, показывают мне, что порядок не важен. Пример со страницы ScalaJsonCombinators в Play Docs:

case class Location(lat: Double, long: Double)

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

implicit val locationWrites: Writes[Location] = (
 (JsPath \ "lat").write[Double] and
 (JsPath \ "long").write[Double]
)(unlift(Location.unapply))

person Barry    schedule 13.09.2014    source источник


Ответы (1)


Это абсолютно связано с порядком комбинаторов и порядком полей в Location.unapply, иначе не было бы детерминированного способа записи Reads и Writes.

implicit val locationWrites: Writes[Location] = (
  (JsPath \ "lat").write[Double] and
  (JsPath \ "long").write[Double]
)(unlift(Location.unapply))

scala> Json.stringify(Json.toJson(Location(2.11, 42.12)))
res2: String = {"lat":2.11,"long":42.12}

Имена путей в Writes не имеют отношения к именам полей Location, они просто применяются по порядку:

// Reversed
implicit val locationWrites: Writes[Location] = (
  (JsPath \ "long").write[Double] and
  (JsPath \ "lat").write[Double]
)(unlift(Location.unapply))

scala> Json.stringify(Json.toJson(Location(2.11, 42.12)))
res3: String = {"long":2.11,"lat":42.12}
person Michael Zajac    schedule 13.09.2014