玩 2.4 参数化代数数据类型 JSON 验证
Posted
技术标签:
【中文标题】玩 2.4 参数化代数数据类型 JSON 验证【英文标题】:Play 2.4 parameterized algebraic data types JSON validation 【发布时间】:2016-04-14 18:50:20 【问题描述】:是否可以在 Scala / Play 2.4 中做类似的事情:
sealed trait Location val `type`: String
case class CityLocation(zip_code: String, override val `type`: String = "city") extends Location
case class AddressLocation(
society: Option[String],
first_name: String,
last_name: String,
...
override val `type`: String = "address"
) extends Location
sealed trait Point[T <: Location] val `type`: String; val location: T
case class ShippingPoint[T](override val location: T, override val `type`: String = "shipping") extends Point[T]
case class PickupPoint[T](override val location: T, override val `type`: String = "pickup") extends Point[T]
object CityLocation
implicit val format = Json.format[CityLocation]
object AddressLocation
implicit val format = Json.format[AddressLocation]
object ShippingPoint
implicit def write[T] = Json.writes[ShippingPoint[T]]
implicit def read[T]: Reads[ShippingPoint[T]] = (
(__ \ "location").read[T] and
(__ \ "type").read[String](exactWordRead("shipping", "error.route.shipping.type"))
)(ShippingPoint[T].apply _)
object PickupPoint
implicit def write[T] = Json.writes[ShippingPoint[T]]
implicit def read[T]: Reads[PickupPoint[T]] = (
(__ \ "location").read[T] and
(__ \ "type").read[String](exactWordRead("pickup", "error.route.pickup.type"))
)(PickupPoint[T].apply _)
??
目前,它无法编译。
exactWordRead
方法定义如下:
def exactWordRead(word: String, errorMessage: String): Reads[String] = Reads.constraints.pattern(s"^$word$"$"".r, errorMessage)
编辑:
由于这个答案https://***.com/a/29834113/2431728,我似乎向前迈出了一步:
sealed trait Location val `type`: String
case class CityLocation(zip_code: String, override val `type`: String = "city") extends Location
case class AddressLocation(
society: Option[String],
first_name: String,
last_name: String,
...
override val `type`: String = "address"
) extends Location
sealed trait Point[T <: Location] val location: T; val `type`: String
case class ShippingPoint[T](override val location: T, override val `type`: String = "shipping") extends Point[T]
case class PickupPoint[T](override val location: T, override val `type`: String = "pickup") extends Point[T]
object CityLocation
implicit val format = Json.format[CityLocation]
object AddressLocation
implicit val format = Json.format[AddressLocation]
object ShippingPoint
implicit def format[T: Format]: Format[ShippingPoint[T]] = (
(__ \ "location").format[T] and
(__ \ "type").format[String](exactWordRead("shipping", "error.route.shipping.type"))
)(ShippingPoint.apply, unlift(ShippingPoint.unapply))
object PickupPoint
implicit def format[T: Format]: Format[PickupPoint[T]] = (
(__ \ "location").format[T] and
(__ \ "type").format[String](exactWordRead("pickup", "error.route.pickup.type"))
)(PickupPoint.apply, unlift(PickupPoint.unapply))
但是,我还没有编译。编译错误是:
[error] type arguments [T] do not conform to trait Point's type parameter bounds [T <: services.coliswebApi.data.Location]
[error] case class ShippingPoint[T](override val location: T, override val `type`: String = "shipping") extends Point[T]
[error] ^
[error] type arguments [T] do not conform to trait Point's type parameter bounds [T <: services.coliswebApi.data.Location]
[error] case class PickupPoint[T](override val location: T, override val `type`: String = "pickup") extends Point[T]
【问题讨论】:
【参考方案1】:正如编译器所说,一方面你有,
sealed trait Point[T <: Location]
...另一方面,
case class ShippingPoint[T](???) extends Point[T]
case class PickupPoint[T](???) extends Point[T]
但ShippingPoint
和PickupPoint
的声明中没有任何内容证明类型参数与约束<: Location
兼容,需要扩展Point
。
所以你需要解决这个问题。
case class ShippingPoint[T <: Location](???) extends Point[T]
case class PickupPoint[T <: Location](???) extends Point[T]
【讨论】:
确实如此。但现在是无法编译的格式。你知道如何纠正它们吗? 原因是一样的。 确实如此。感谢您的帮助 =)【参考方案2】:我认为您还需要像这样以格式绑定您的类型
implicit def format[T <: Location: Format]: Format[ShippingPoint[T]] = (
(__ \ "location").format[T] and
(__ \ "type").format[String](exactWordRead("shipping", "error.route.shipping.type"))
)(ShippingPoint.apply, unlift(ShippingPoint.unapply))
【讨论】:
它编译! Thaaaanks 很多 =D以上是关于玩 2.4 参数化代数数据类型 JSON 验证的主要内容,如果未能解决你的问题,请参考以下文章