0

我正试图围绕 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

4

1 回答 1

0

因此,在研究了示例之后,我想我终于深入了解了参数函数的工作原理:

def parameter(pdm: ParamDefMagnet): pdm.Out = pdm()

提取字符串类型参数的示例:

val p: Directive1[String] = parameter("name")

// we can then apply the function with the extracted name
p { name => 
   // stuff
}

Spray 使用了一堆隐式转换,但基本上,如果你有 aString和 a String => Directive1[String],你可以构造 a () => 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")

有关如何以Directive1[String]DSL 方式应用 a,请参阅指令如何在 Spray 中工作?

于 2015-04-23T23:51:02.827 回答