我试图了解Spray如何实施其指令,特别是参数提取DSL。
我理解磁体模式(几乎没有),但我仍然坚持ParamDefMagnet和ParamDefMagnet2如何协同工作。
def parameter(pdm: ParamDefMagnet): pdm.Out = pdm()
trait ParamDefMagnet {
type Out
def apply(): Out
}
trait ParamDefMagnet2[T] {
type Out
def apply(value: T): Out
}
type ParamDefMagnetAux[A, B] = ParamDefMagnet2[A] { type Out = B }
def ParamDefMagnetAux[A, B](f: A ⇒ B) = new ParamDefMagnet2[A] { type Out = B; def apply(value: A) = f(value) }
我试图弄清楚如何通过下面的隐式方法将ParamDefManget2隐式转换为ParamDefMagnet。
object ParamDefMagnet {
implicit def apply[T](value: T)(implicit pdm2: ParamDefMagnet2[T]) = new ParamDefMagnet {
type Out = pdm2.Out
def apply() = pdm2(value)
}
}
如果我致电parameter("name")
,"姓名"隐式转换为ParamDefMagnet
?如果它首先将其转换为ParamDefMagnet2
,那么value: T
来自哪里才能将其转换为ParamDefMagnet
?
答案 0 :(得分:0)
因此,在深入研究示例后,我认为我终于找到了参数函数的工作原理:
def parameter(pdm: ParamDefMagnet): pdm.Out = pdm()
提取String类型参数的示例:
val p: Directive1[String] = parameter("name")
// we can then apply the function with the extracted name
p { name =>
// stuff
}
Spray使用了大量隐式转换,但基本上,如果您有String
和String => Directive1[String]
,则可以构建() => Directive1[String]
:
// Our String => Directive1[String]
val pdm2: ParamDefMagnet2[String] { type Out = Directive1[String] } = ParamDefMagnet2.fromString
// Our () => Directive1[String]
val pdm: ParamDefMagnet { type Out = Directive1[String] } = new ParamDefMagnet {
type Out = Directive1[String]
def apply() = pdm2("name")
}
val directive: Directive1[String] = pdm()
// equivalent to:
val directive2: Directive1[String] = parameter("name")
所有这些都构成了简单的parameter("name")
调用:
val p: Directive1[String] = parameter("name")
有关如何以DSL-ey方式应用Directive1[String]
,请参阅How do directives work in Spray?