Scala 参数模式(喷雾路由示例)

标签 scala spray shapeless

抱歉标题含糊……不知道如何描述这一点。

一段时间以来,我已经在 Scala 中看到/使用了某种代码结构,但我不知道它是如何工作的。它看起来像这样(来自喷雾路由的示例):

path( "foo" / Segment / Segment ) { (a,b) => {  // <-- What's this style with a,b?
...
}}

在此示例中,路径中的分段分别绑定(bind)到关联 block 内的 a 和 b。我知道如何使用这种模式,但它是如何工作的?为什么它没有将某些东西绑定(bind)到“foo”?

我对喷雾如何在这里达到我的目的不太感兴趣,但是这是 Scala 的什么工具,我将如何编写自己的工具?

最佳答案

此代码来自扩展 Directives 的类.所以Directives的所有方法在范围内。

路径匹配器

没有方法/String , 所以 an implicit conversion用于转换StringPathMatcher0 ( PathMatcher[HNil] ) 与 method / .

方法/需要 PathMatcher并返回 PathMatcher .

Segment PathMatcher1[String] (PathMatcher[String :: HNil])。

方法/PathMatcher[HNil]PathMatcher[String :: HNil]参数返回 PathMatcher[String :: HNil] .

方法/PathMatcher[String :: HNil]PathMatcher[String :: HNil]参数返回 PathMatcher[String :: String :: HNil] .这是来自 shapeless 的黑魔法.查看异构列表 concatenation ;值得一读。

指示

所以你调用method path PathMatcher[String :: String :: HNil]作为参数。它返回一个 Directive[String :: String :: HNil] .

然后你调用方法 applyDirectiveFunction2[?, ?, ?] ( (a, b) => .. ) 作为参数。每个 Directive[A :: B :: C ...] 都有一个适当的隐式转换(参见黑魔法)。使用方法 apply((a: A, b: B, c: C ...) => Route) 创建一个对象.

解析
PathMatcher包含路径解析规则。它以 HList 的形式返回结果.

"foo"匹配器 matches一个字符串并忽略它(返回 HNil )。
A / B matcher 结合了 2 个匹配器( AB ),由“/”字符串分隔。它连接 A 的结果和 B使用 HList级联。
Segment匹配器 matches路径段并将其作为 String :: HNil 返回.

所以"foo" / Segment / Segment匹配 3 个段的路径,忽略第一个段并将剩余段返回为 String :: String :: HNil .

然后黑魔法允许你使用Function2[String, String, Route] ( (String, String) => Route ) 处理 String :: String :: HNil .如果没有这样的魔法,你将不得不使用这样的方法:{case a :: b :: HNil => ...} .

黑魔法

正如@AlexIv 所说:

存在隐式转换 pimpApply 对于每个 Directive[A :: B :: C ...]使用方法 apply((a: A, b: B, c: C ...) => Route) 创建一个对象.

它接受 ApplyConverter含蓄地。成员(member) In ApplyConverter表示一个合适的函数(A, B, C ...) => Route对于每个 Directive[A :: B :: C ...] .

如果没有宏或样板代码,就无法创建此类隐式值。所以 sbt-boilerplate 用于 ApplyConverter一代。见 ApplyConverterInstances.scala .

关于Scala 参数模式(喷雾路由示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18395023/

相关文章:

http - 如何使喷雾 jar 客户端遵循重定向

scala - 如何在单个路由中解码 POST 参数和 JSON 正文?

scala - 将 List[OF[C]] 转换为 F[B],其中案例类 B 的类型与 A 对齐

list - 过滤元组列表

scala - 使用前移除 Spark RDD block

scala - 从Scala读取Parquet文件而不使用Spark

json - 无法使用 json4s 正确提取 json

java - Spark 作业服务器 : "The server was not able to produce a timely response to your request"

java - 仅在 Spark 中可见的 Shapeless 中的 NoSuchMethodError

scala - HList 中的类型类包含元素?