我定义了一个这样的联合类型:
import play.api.libs.json._
import reactivemongo.play.json._
import reactivemongo.play.json.collection.JSONCollection
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
object Models {
sealed trait BiosChannel {
val id : Int
val label : String
val samplingRate : Int
val scaleFactor : Double
}
case class CCWBiosChannel
(
id : Int,
label : String,
samplingRate : Int,
scaleFactor : Double
) extends BiosChannel
case class NNBiosChannel
(
id : Int,
label : String,
samplingRate : Int,
scaleFactor : Double,
amplitude : Double,
position : Option[String],
localisation : Option[List[Double]]
) extends BiosChannel
implicit val biosChannelReads = {
val ccwBiosChannel = Json.reads[CCWBiosChannel]
val nnBiosChannel = Json.reads[NNBiosChannel]
__.read[CCWBiosChannel](ccwBiosChannel).map(x => x : BiosChannel) |
__.read[NNBiosChannel](nnBiosChannel).map(x => x : BiosChannel)
}
implicit val biosChannelWrites = Writes[BiosChannel] {
case ccwBiosChannel : CCWBiosChannel =>
Json.writes[CCWBiosChannel].writes(ccwBiosChannel)
case nnBiosChannel : NNBiosChannel =>
Json.writes[NNBiosChannel].writes(nnBiosChannel)
}
}
然后,我编写了一些单元测试,以检查是否可以序列化和反序列化CCWBiosChannel和NNBiosChannel。我尝试编写一个采用泛型类型T的函数,因为我想重用以下函数:
import org.scalatest._
import play.api.libs.json._
import BiosModels._
class BiosModelsSpec extends FlatSpec with Matchers {
def serializeAndDeserialize[T](implicit reads : Reads[T], writes : Writes[T]) =
((x : T) => Json.toJson(x)) andThen ((y) => y.validate[BiosRecord].get)
val ccwBiosChannels = List(CCWBiosChannel(0, "",-1,0.0, ChannelType.ECG, Units.mV, blocks))
val ccwBiosEvents = List(CCWBiosEvent(0L,0L,Some(""), CCWEventType.NOTWORN, CCWEventSource.mELEC))
val ccwBiosRecord = CCWBiosRecord("", "", 0L, 0L,1, ccwBiosChannels, Some(ccwBiosEvents))
serializeAndDeserialize(ccwBiosChannel) // compilation error here
}
我在编译中遇到一个错误:
not enough arguments for method serializeAndDeserialize: (implicit reads: play.api.libs.json.Reads[T], implicit writes: play.api.libs.json.Writes[T])T => com.bioserenity.core.data.BiosModels.BiosRecord.
[error] Unspecified value parameter writes.
[error] serializeAndDeserialize(ccwBiosChannel)
我无法理解的是我为我的case类定义了隐式读/写。此外,必须不要像我的错误那样需要implicits参数。那么我的代码有什么问题呢?
答案 0 :(得分:1)
我建议在隐式读写定义上设置一个显式类型,如下所示:
implicit val biosChannelReads: Reads[BiosChannel] = {
val ccwBiosChannel = Json.reads[CCWBiosChannel]
val nnBiosChannel = Json.reads[NNBiosChannel]
__.read[CCWBiosChannel](ccwBiosChannel).map(x => x : BiosChannel) |
__.read[NNBiosChannel](nnBiosChannel).map(x => x : BiosChannel)
}
implicit val biosChannelWrites: Writes[BiosChannel] = Writes[BiosChannel] {
case ccwBiosChannel : CCWBiosChannel =>
Json.writes[CCWBiosChannel].writes(ccwBiosChannel)
case nnBiosChannel : NNBiosChannel =>
Json.writes[NNBiosChannel].writes(nnBiosChannel)
}
然后修改serialize / deserialize方法,如下所示:
def serializeAndDeserialize[T, V](x: T)(implicit reads : Reads[V], writes : Writes[T]): V = {
Json.toJson(x).validate[V].get
}
然后您可以通过以下方式调用它(根据需要填写类型):
serializeAndDeserialize[List[<input type here>], List[<output type here>]](ccwBiosChannels)