锄头做喷涂参数有效吗?

时间:2015-04-23 06:27:34

标签: scala spray spray-dsl

我试图了解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

1 个答案:

答案 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使用了大量隐式转换,但基本上,如果您有StringString => 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?