【问题标题】:How do I write generic implicit conversion?如何编写泛型隐式转换?
【发布时间】:2013-08-06 01:01:12
【问题描述】:

你能帮我写泛型隐式转换吗?

我正在使用 Scala 2.10.2 和 Spray 1.2。

这就是我所拥有的

// for "parameters"
implicit def ObjectIdUnmarshallerString = new Deserializer[String, ObjectId] {
  def apply(value: String) =
    try Right(new ObjectId(value))
    catch {
      case ex: Throwable => Left(MalformedContent(s"Cannot parse: $value", ex))
    }
}

//  for "formParameters"
implicit def ObjectIdUnmarshallerHttpEntity = new Deserializer[HttpEntity, ObjectId] {
  def apply(value: HttpEntity) = ObjectIdUnmarshallerString(value.asString)
}

如您所见,HttpEntity->ObjectId 的反序列化器仅使用 String->ObjectId 反序列化器。我必须为我在 HTTP 路由特征中使用的每个类复制粘贴这样的代码。

所以我想如果我可以编写通用的 HttpEntity->T,它将使用范围内可用的Deserializer[String, T]。

我试过了:

  implicit def GenericUnmarshallerHttpEntity[T] = new Deserializer[HttpEntity, T] {
    def convertAsString(value: HttpEntity)(implicit conv: Deserializer[String, T]) = conv(value.asString)

    def apply(value: HttpEntity) = convertAsString(value)
  }

很遗憾,它不起作用。并说:

could not find implicit value for parameter conv: spray.httpx.unmarshalling.Deserializer[String,T]
    def apply(value: HttpEntity) = convertAsString(value)
                                                  ^

not enough arguments for method convertAsString: (implicit conv: spray.httpx.unmarshalling.Deserializer[String,T])spray.httpx.unmarshalling.Deserialized[T].
Unspecified value parameter conv.
    def apply(value: HttpEntity) = convertAsString(value)
                                                  ^

你能建议怎么做吗?

【问题讨论】:

  • 尝试 implicit def GenericUnmarshallerHttpEntity[T](implicit conv: Deserializer[String, T]) = ... 并从 converAsString 中删除隐式参数
  • @LuigiPlinge 它有帮助!您能否粘贴您的评论作为答案?

标签: scala generics implicit-conversion spray


【解决方案1】:

尝试implicit def GenericUnmarshallerHttpEntity[T](implicit conv: Deserializer[String, T]) = ... 并从convertAsString 中删除隐式参数。

就问题而言,apply 不需要隐式在范围内,因此它不能调用 convertAsString 方法。

【讨论】:

    【解决方案2】:

    您的 apply 函数需要将隐式传递给 convert 方法

    implicit def GenericUnmarshallerHttpEntity[T] = new Deserializer[HttpEntity, T] {
      def convertAsString(value: HttpEntity)(implicit conv: Deserializer[String, T]) = conv(value.asString)
    
      def apply(value: HttpEntity)(implicit conv: Deserializer[String, T]) = convertAsString(value)
    }
    

    【讨论】:

    • 不幸的是我试过了。编译器说object creation impossible, since method apply in trait Function1 of type (v1: spray.http.HttpEntity)spray.httpx.unmarshalling.Deserialized[T] is not defined (Note that T1 does not match spray.http.HttpEntity) implicit def GenericUnmarshallerHttpEntity[T] = new Deserializer[HttpEntity, T] { ^
    猜你喜欢
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2017-09-10
    • 2018-12-08
    相关资源
    最近更新 更多