理解 Scala 块
Posted
技术标签:
【中文标题】理解 Scala 块【英文标题】:Understanding Scala Blocks 【发布时间】:2013-10-01 04:53:44 【问题描述】:对于我所知道的微不足道的事情,我很难找到具体的答案。我想了解块在 Scala 中是如何工作的。我来自 java/ruby 背景,似乎 scala 使用块的方式完全不同。
以下代码来自Play! Framework website。我想从语义上了解 Action 是什么。它是接受块的对象还是函数,或者两者都不接受。
object Application extends Controller
def index = Action
Ok(views.html.index("Your new application is ready."))
如果它是一个函数,也许它是以下的语法糖(在这种情况下,scala 如何在幕后绕过块):
def index = Action(
Ok(views.html.index("Your new application is ready."))
)
或者是我不知道的一些 scala 语法。
任何对 Scala 源代码的引用都将帮助我了解它是如何在幕后工作的。
【问题讨论】:
【参考方案1】:这里发生了一些事情。 Action
是一个实现 apply()
方法的对象,当您将对象视为函数时,会调用什么。有几个apply()
implementations。第一个实现使用按名称参数。
Scala 支持称为“按名称参数”的概念,它与普通参数一样,只是它们仅在引用它们的代码执行时才被评估。它们有助于创建看起来像是语言一部分的结构,而无需借助宏。在这种情况下,Ok(..)
周围的块只是一个常规的语句块,最后一个的值被用作块的值。您提供的示例在没有大括号的情况下也可以工作。您实际上只是将 Ok 的 apply
方法的结果传递给 Action
的 apply
方法。
apply()
的第二个版本确实采用了一个完整的匿名函数,它将请求映射到结果。在这种情况下,您可以传递一个匿名(或命名)函数。
【讨论】:
感谢您的回复。所以从我收集的信息来看,这是 Action.apply() 的语法糖。去掉糖,整个语句会是什么样子? 您拥有的声明本质上是Action.apply(Ok.apply(views.html.index("Your new application is ready.")))
。如果您查看我提供的 URL 中apply()
的定义,您会注意到参数类型前面有一个箭头。这只是将其标记为“按名称”参数,如上所述。 (另外,by-name 的语法看起来像不带参数的匿名函数也不是巧合)
顺便说一句,播放文档的链接已损坏。有时,SO 解析器会弄乱包含美元符号的链接。【参考方案2】:
您最好将 scala 块视为 java 匿名类(例如 Guava Functions)而不是 ruby 块。实际上,如果你反编译 scala 代码,你会看到或多或少相同的代码(taken from Guava examples):
Function<String, Integer> lengthFunction = new Function<String, Integer>()
public Integer apply(String string)
return string.length();
;
不同的是,scala提供了很多语法糖,允许你把上面的代码写成:
val lengthFunction = string: String => string.length
至于具体的Action例子:
def index = Action(
Ok(views.html.index("Your new application is ready."))
)
这里的 Action 可能是带有 apply 方法的对象。另一种 scala 糖:语言允许你写 Foo(bar)
和表示 Foo.apply(bar)
。接下来,you can drop round braces when your call isn't ambiguous,所以是的,它实际上是一个被调用的方法:
def index = Action(
Ok(views.html.index("Your new application is ready."))
)
并且有这样的东西作为签名:
object Action
def apply(block: => Result) = ???
正如@yan 已经说过的那样,这是 scala 的说法 嘿,我是一个接受另一个产生结果的函数的函数
脱糖调用看起来像
def index = Action.apply(new AbstractFunction[Result]
def apply() = Ok.apply(views.html.index.apply("..."))
)
【讨论】:
以上是关于理解 Scala 块的主要内容,如果未能解决你的问题,请参考以下文章