这段Scala代码是用来做什么的?

3

我还不熟悉Scala语言,发现了Spray框架中的这段代码。

我试图了解这个方法签名的含义:

 /**
 * Completes the request using the given arguments.
 */
def complete: (⇒ ToResponseMarshallable) ⇒ StandardRoute = marshallable ⇒ new StandardRoute {
  def apply(ctx: RequestContext): Unit = ctx.complete(marshallable)
}

这里的=>运算符是用来做什么的?我原以为它是用来创建闭包的? 这里对marshallable进行了赋值操作,为什么要在括号外面赋值?
希望能看到这段代码的Java版本。

可能是Scala中=>和() =>的含义是什么的重复问题。 - Chris Martin
不是。正如我之前提到的,=> 表示创建一个闭包。但是我不理解它在这里签名上下文中的含义。 - pdeva
这也意味着其他事情,正如在那个问题的第二个答案中所解释的那样。 - Chris Martin
1
尽管通常情况可能已经在那个问题中得到了足够的涵盖,但我认为实际上这还是相当棘手的解析。我会尝试回答它。 - Steve Waldman
1个回答

3

所以。

首先要注意的是,complete 是一个使用 def 声明的方法,因此它是一个方法,但是看起来像方法参数的括号在冒号 : 之后。

因此,它们实际上不是方法参数。 complete 是一个无参方法!

那么冒号后面的括号怎么回事?

(⇒ ToResponseMarshallable) ⇒ StandardRoute 是无参方法 complete 的 返回类型。函数 complete 返回一个函数,该函数接受类型为 ToResponseMarshallable 的表达式并返回一个 StandardRoute

好了。但是,在函数签名 (⇒ ToResponseMarshallable) ⇒ StandardRoute 中,ToResponseMarshallable 之前的箭头是什么意思?

在函数签名中,类型名称之前的 表示 "按名称调用" 参数。遵循 Java,Scala 默认评估参数列表中的所有表达式,然后评估方法体,并将评估的值替换为变量。但是 Scala 还支持按名称调用语义,其中一个 表达式 未评估地替换为函数,并在每次命名时重新执行。 complete 返回一个其单个参数具有按名称调用语义的函数。

等号后面只是这个方法的实现。以 marshallable ⇒ 开头的表达式是匿名函数、函数文本或 lambda(基本上是同一件事的所有名称)。marshallable ⇒ "hello" 将是一个接受(按名称)ToResponseMarshallable 并返回字符串 "hello" 的函数。但是我们需要一个接受 ToResponseMarshallable(按名称)并返回 StandardRoute 的方法。因此,我们有 marshallable ⇒<求值为 StandardRoute 的表达式>

那个 <求值为 StandardRoute 的表达式> 只是一个匿名内部类,它实现了它的 apply 方法。

我们完成了!我们(希望)理解了所有组件及其声明的含义。


你说,“complete”返回一个接受类型为StandardRoute的表达式的函数,但是返回的函数不是返回StandardRoute(而是接受它)吗? - pdeva
啊!是的。让我修复它,假装这没发生过。 - Steve Waldman
那就是我想说的。 - Steve Waldman
我已经很久没有认真看Spray了。但是看起来 ToResponseMarshallable 只是一个可以转换为HTTP响应的东西的句柄。如果传递给 complete 函数返回的东西通常是XML、JSON或纯文本字符串之类的东西,那么我猜测会有隐式转换为 ToResponseMarshallable。如果你想传回特殊的东西,你需要定义转换。但这只是我的猜测!(参见 http://stackoverflow.com/questions/28130260/required-spray-httpx-marshalling-toresponsemarshallable-error) - Steve Waldman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接