我很清楚喷雾器中磁铁的作用是多么的容易,但是在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在FieldDefMagnet.apply("name")中封装"name"时,如何选择和应用其他关联呢?
发布于 2013-10-14 10:28:50
是的,它从FieldDefMagnet.apply开始,然后继续查找apply方法的内嵌,以此类推。
粗略地说,FieldDefMagnet是1)一个带有隐式功能注释的值,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)))))))https://stackoverflow.com/questions/19357058
复制相似问题