Scala类型参数不符合错误

时间:2018-01-16 23:24:13

标签: scala types

我有以下类型转换器:

import scala.concurrent.duration._

/**
  * Type classes that define the message transformations to and fro between JSON and
  * case class types
  */
object JsonMessageConversion {
  implicit val resolveTimeout: Timeout = Timeout(3.seconds)

  case class FailedMessageConversion(kafkaTopic: String, msg: String, msgType: String)

  trait Converter[T <: KafkaMessage] {
      def convertFromJson(msg: String): Either[FailedMessageConversion, T]
      def convertToJson(msg: T): String
  }

  //Here is where we create implicit objects for each Message Type you wish to convert to/from JSON
  object Converter {

    val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    implicit val jodaDateTimeReads: Reads[DateTime] = Reads[DateTime](js =>
      js.validate[String].map[DateTime](dt =>
        DateTime.parse(dt, DateTimeFormat.forPattern(dateFormat))
      )
    )

    implicit val jodaDateTimeWrites: Writes[DateTime] = new Writes[DateTime] {
      def writes(dt: DateTime): JsValue = JsString(dt.toString())
    }

    implicit object DefaultMessageConverter extends Converter[DefaultMessage] {

      implicit val defaultMessageReads: Reads[DefaultMessage] = (
        (__ \ "message").read[String] and
        (__ \ "timestamp").read[DateTime](jodaDateTimeReads)
      )(DefaultMessage.apply _)

      implicit val defaultMessageWrites: Writes[DefaultMessage] = (
        (__ \ "message").write[String] and
        (__ \ "timestamp").write[DateTime](jodaDateTimeWrites)
      )(unlift(DefaultMessage.unapply))

      implicit val defaultMessageFormat: Format[DefaultMessage] =
        Format(defaultMessageReads, defaultMessageWrites)

      override def convertFromJson(msg: String): Either[FailedMessageConversion, DefaultMessage] = {
        Json.parse(msg).validate[DefaultMessage] match {
          case s: JsSuccess[DefaultMessage] => Right(s.value)
          case _: JsError => Left(FailedMessageConversion("kafkaTopic", msg, "to: DefaultMessage"))
        }
      }

      override def convertToJson(msg: DefaultMessage): String = {
        Json.toJson(msg).toString()
      }
    }

    implicit object DefaultMessageBundleConverter extends Converter[DefaultMessageBundle] {

      implicit val defaultMessageReads = Converter.DefaultMessageConverter.defaultMessageReads
      implicit val defaultMessageWrites = Converter.DefaultMessageConverter.defaultMessageWrites

      implicit val defaultMessageBundleReads: Reads[DefaultMessageBundle] = (
        (__ \ "messages").read[Seq[DefaultMessage]] and
          (__ \ "timestamp").read[DateTime](jodaDateTimeReads)
        )(DefaultMessageBundle.apply _)

      implicit val defaultMessageBundleWrites: Writes[DefaultMessageBundle] = (
        (__ \ "messages").write[Seq[DefaultMessage]] and
          (__ \ "timestamp").write[DateTime](jodaDateTimeWrites)
        )(unlift(DefaultMessageBundle.unapply))

      implicit val defaultMessageFormat: Format[DefaultMessageBundle] =
        Format(defaultMessageBundleReads, defaultMessageBundleWrites)

      override def convertFromJson(msg: String): Either[FailedMessageConversion, DefaultMessageBundle] = {
        Json.parse(msg).validate[DefaultMessageBundle] match {
          case s: JsSuccess[DefaultMessageBundle] => Right(s.value)
          case _: JsError => Left(FailedMessageConversion("kafkaTopic", msg, "to: DefaultMessageBundle"))
        }
      }

      override def convertToJson(msg: DefaultMessageBundle): String = {
        Json.toJson(msg).toString()
      }
    }

    def apply[T: Converter] : Converter[T] = implicitly
  }
}

编译时出错:

Error:(98, 16) type arguments [T] do not conform to trait Converter's type parameter bounds [T <: com.eon.pm.messages.KafkaMessage]
    def apply[T: Converter] : Converter[T] = implicitly

如何摆脱这个错误?

1 个答案:

答案 0 :(得分:1)

只需添加绑定到该方法的相同类型:

def apply[T <: KafkaMessage : Converter] : Converter[T] = implicitly

我不确定为什么编译器需要这种冗余,但这可以消除错误。