我试图通过尝试使用Scalatra来尝试进入Scala。我不久前在课程上完成了Martin Odersky的课程,但我仍然很难理解这是如何工作的:
package com.example.app
import org.scalatra._
class HelloWorldApp extends ScalatraFilter {
get("/") {
<h1>Hello, {params("name")}</h1>
}
}
此示例来自Scalatra主页:http://www.scalatra.org/
如何执行此声明:
get("/") { Hello, {params("name")} }
{}
是get()
方法的参数吗?
你能解释一下Scala语言的哪些特性在用吗? Scalatra源代码的指针将是完美的定义,这将是完美的。
答案 0 :(得分:8)
get
在CoreDsl中定义如下
def get(transformers: RouteTransformer*)(block: => Any): Route
因此,get
采用两个参数,一系列路由变换器(字符串被隐式转换为路由变换器)和一个无参数方法,输出Any
类型的东西。这里有趣的部分是第二个参数。
首先要理解的是,无参数方法作为函数参数是在Scala中专门处理的,即按名称调用,请参阅Automatic Type-Dependent Closure Construction和Scala Language Reference, Section 6.6, p. 78, which is p. 86 of the PDF:
带有无参数方法类型
=> T
的形式参数的情况 特别对待。在这种情况下,相应的实际参数 在应用程序之前不评估表达式e
。相反,每一个 在重写规则的右侧使用形式参数 需要重新评估e
。换句话说,评估顺序 对于=>
- 参数是按名称调用而评估顺序是 正常参数是按值调用。
第二个方面是在函数应用程序中,参数可以包含在()
(&#34;常规&#34;参数)或{}
中(更准确地说,在这种情况下,它们必须是block expressions,他们甚至可以开始新的一行),请参阅Scala Language Reference on Function Application, Section 6.6 on p. 77, which is p. 85 of the PDF。
另请注意,这两个功能是如何使Scala成为定义DSL(或类似关键字的新功能)的有吸引力的语言的重要组成部分。
以下问题的某些部分可能也很有趣What's the difference between multiple parameters lists and multiple parameters per list in Scala?
答案 1 :(得分:1)
{}是get()方法的参数吗?
是。 get
将有两个参数列表。一个用于路径"\"
,另一个用于块执行。块包含在{}
中,()
中的参数。所以你似乎必须将其称为
class HelloWorldApp extends ScalatraFilter {
get("/") ({
<h1>Hello, {params("name")}</h1>
})
}
但是有一些语法糖允许传递{}
中的单个参数而无需添加()
。你会在
myList foreach { do_something() }
它是一个非常有用的功能,用于编写外观,并且像新的控制结构一样使用,但实际上只是函数。