1

我是新来喷涂的。我使用过几种奇怪的(对我而言)编程语言,如 python、JQuery 等……有了它们,我至少可以理解一些代码段的作用。不幸的是,使用 Spray,我什至无法阅读和理解一个简单的代码。

有人可以帮我阅读(用文字描述,代码做什么)以下简单的代码块。

注意:我知道非常高级,这将选择 url 参数并将它们添加在一起。但我想要的是,清楚地理解这个代码块水晶,因为我可以教给别人。HNil, Directive1, Directive1, ::对我来说有些奇怪。

val twoIntParameters: Directive[Int :: Int :: HNil] =
  parameters('a.as[Int], 'b.as[Int])

val myDirective: Directive1[String] =
  twoIntParameters.hmap {
    case a :: b :: HNil => (a + b).toString
  }

// test `myDirective` using the testkit DSL
Get("/?a=2&b=5") ~> myDirective(x => complete(x)) ~> check {
  responseAs[String] === "7"
}
4

2 回答 2

3

喷雾路由是围绕Directive.

您可以将 aDirective视为对 HTTP 请求的转换。

与指令关联的基数是在执行转换后沿转换链传递的参数数量。

Directive0是一个不提供(或提取)任何参数的指令。

Directive1[A]提供一个类型的参数A

Directive[A :: B :: HNil]提供 2 个类型的参数Aand B,或者 - 更准确地说 - 提供由Aand组成的异构列表B(实现是无形的HList)。

让我们以您的代码中的示例为例

val twoIntParameters: Directive[Int :: Int :: HNil] =
  parameters('a.as[Int], 'b.as[Int])

您正在定义一个从 HTTP 请求中提取两个整数的新指令,即类型为Directive[Int :: Int :: HNil]. 该实现只是利用了 spray 已经提供的指令,即parameters. parameters是一个指令,允许从 HTTP 请求中提取查询参数并将它们转换为特定类型,在本例Int中为两个参数。

val myDirective: Directive1[String] =
  twoIntParameters.hmap {
    case a :: b :: HNil => (a + b).toString
  }

myDirective是一个提取类型参数的指令String

它的实现使用先前定义的twoIntParameters指令并映射其结果,对其应用转换。在这种情况下,我们将两者Int相加,然后将结果转换为String

那么,怎么了hmap?这只是使用返回无形的指令的喷雾提供的一种方式HListhmap需要一个HList对任何东西都有效的函数,在这种情况下是 a String

HLists 可以进行模式匹配,就像普通的 scala 一样List,这就是您在示例中看到的。

最后,这只是从功能的角度来看指令如何工作的一个想法。如果您想了解 DSL 语法的详细信息,则必须进一步挖掘并阅读有关Magnet Pattern的信息。

于 2015-09-16T12:29:43.453 回答
0

在这里,我找到了一个非常好的工作室。

https://www.youtube.com/watch?v=XPuOlpWEvmw

于 2015-10-01T12:20:35.203 回答