我清楚地知道Spray中的磁铁是如何容易的,但是FieldDefMagnet中的所有转换和隐含只是让我的脑筋流露。以下是sources:
中的部分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")
,但是如何选择和应用其他含义?
答案 0 :(得分: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)))))))