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()

String 型のパラメーターを抽出する例:

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

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

スプレーは一連の暗黙的な変換を使用しますが、基本的に、 aStringと aがある場合、 aString => 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")

Directive1[String]aが DSL-ey の方法でどのように適用されるかについては、「ディレクティブはスプレーでどのように機能しますか?」を参照してください。

于 2015-04-23T23:51:02.827 に答える