b1n*_*1nd 20 scala block playframework
我很难找到具体的答案,我所知道的是微不足道的.我想了解块如何在Scala中工作.我来自java/ruby背景,似乎scala有一种完全不同的使用块的方式.
以下代码来自Play!框架网站.我想了解Action在语义上是什么.是接受块的对象还是函数,或者两者都不接受.
object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
Run Code Online (Sandbox Code Playgroud)
如果它是一个函数,也许它是以下的语法糖(在这种情况下scala如何在幕后传递块):
def index = Action({
Ok(views.html.index("Your new application is ready."))
})
Run Code Online (Sandbox Code Playgroud)
或者它是一些我不知道的scala语法.
对Scala源代码的任何引用都将帮助我理解它在幕后的工作原理.
om-*_*nom 22
你最好将scala块视为java匿名类(例如像Guava Functions)而不是ruby块.实际上,如果您反编译scala代码,您将看到或多或少相同的代码(取自Guava示例):
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
public Integer apply(String string) {
return string.length();
}
};
Run Code Online (Sandbox Code Playgroud)
区别在于scala提供了大量的语法糖,并允许您将上面的代码编写为:
val lengthFunction = { string: String => string.length }
Run Code Online (Sandbox Code Playgroud)
至于具体的动作示例:
def index = Action({
Ok(views.html.index("Your new application is ready."))
})
Run Code Online (Sandbox Code Playgroud)
这里Action可能是apply方法的对象.另一种scala糖:语言允许你写Foo(bar)和意思Foo.apply(bar).接下来,当您的调用不明确时,您可以丢弃圆括号,所以是的,它实际上是一个被调用的方法:
def index = Action({
Ok(views.html.index("Your new application is ready."))
})
Run Code Online (Sandbox Code Playgroud)
并将这样的东西作为签名:
object Action {
def apply(block: => Result) = ???
}
Run Code Online (Sandbox Code Playgroud)
正如@yan已经说过的那样,scala的方式是嘿,我是一个接受另一个产生Result的函数的函数
Desugared调用看起来像
def index = Action.apply(new AbstractFunction[Result] {
def apply() = Ok.apply(views.html.index.apply("..."))
})
Run Code Online (Sandbox Code Playgroud)
这里有一些事情发生.Action是一个实现apply()方法的对象,当您将对象视为函数时,会调用什么.有一些apply() 实现.第一个实现使用by-name参数.
Scala支持一种称为"按名称参数"的概念,它与普通参数类似,只是在执行引用它们的代码时才会对它们进行评估.它们有助于创建看起来像是语言一部分而不需要使用宏的构造.在这种情况下,块周围Ok(..)只是一个常规语句块,最后一个值用作块的值.您提供的示例也可以在没有大括号的情况下工作.你基本上只是路过确定的结果apply方法Action的apply方法.
第二个版本apply()确实采用了一个完整的匿名函数,它将请求映射到结果.在这种情况下,您可以传递匿名(或命名)函数.