1

我清楚地了解 Spray 中的磁铁是如何工作的,但 FieldDefMagnet 中的所有转换和隐式都让我大吃一惊。以下是来源的部分:

def formField(fdm: FieldDefMagnet): fdm.Out = fdm()

trait FieldDefMagnet {
  type Out
  def apply(): Out
}
object FieldDefMagnet {
  implicit def apply[T](value: T)(implicit fdm2: FieldDefMagnet2[T]) = new FieldDefMagnet {
    type Out = fdm2.Out
    def apply() = fdm2(value)
  }
}
trait FieldDefMagnet2[T] {
  type Out
  def apply(value: T): Out
}
object FieldDefMagnet2 {
  implicit def apply[A, B](implicit fdma: FieldDefMagnetAux[A, B]) = new FieldDefMagnet2[A] {
    type Out = B
    def apply(value: A) = fdma(value)
  }
}

trait FieldDefMagnetAux[A, B] extends (A ⇒ B)

因此,例如,当我调用formField("name")scalac 换行时"name"FieldDefMagnet.apply("name")如何选择和应用其他隐式?

4

1 回答 1

1

是的,它从你所说的开始FieldDefMagnet.apply,然后继续寻找apply方法的隐含,以此类推,以获取完整的隐含链。

粗略地说,FieldDefMagnet是 1) 用 2) 隐式功能和 3) 功能的返回类型注释的值。

FieldDefMagnet2只是返回类型的类型成员的隐式功能。

FieldDefMagnetAux只是为Out类型成员提供更简单的语法。它也可以写成(也许我们应该这样做)

type FieldDefMagnetAux[A, B] = FieldDefMagnet2[A] { type Out = B }

基本上需要这个结构来引导类型推断,使 scala 编译器推断出大多数类型参数。

所有“有趣”的东西都发生在FieldDefMagnetAux为不同类型的输入类型计算出相应功能的地方。

编辑:要查看它的实际效果,请考虑将formField("name")其扩展为

formField(
    FieldDefMagnet.apply[String]("name")(
      FieldDefMagnet2.apply[String, Directive1[String]](
        FieldDefMagnetAux.forString(
          Deserializer.fromRequestUnmarshaller[spray.http.HttpForm](
            Deserializer.fromMessageUnmarshaller[spray.http.HttpForm](
              Deserializer.formUnmarshaller(
                Deserializer.UrlEncodedFormDataUnmarshaller, Deserializer.MultipartFormDataUnmarshaller))), 
          FormFieldConverter.dualModeFormFieldConverter[String](
            Deserializer.liftToSourceOption[String, String](
              Deserializer.fromFunction2Converter[String, String](Predef.conforms[String])), 
            Deserializer.liftFromEntityOptionUnmarshaller[String](
              Deserializer.liftToSourceOption[spray.http.HttpEntity, String](
                Deserializer.StringUnmarshaller)))))))
于 2013-10-14T10:28:50.737 回答