这是示例代码:
import spray.routing.SimpleRoutingApp
object Main extends App with SimpleRoutingApp {
implicit val system = ActorSystem("my-system")
startServer(interface = "localhost", port = 8080) {
path("hello") {
get {
complete {
<h1>Say hello to spray</h1>
}
}
}
}
}
发现于http://spray.io/documentation/1.1-SNAPSHOT/spray-routing/#spray-routing
请原谅我的笨拙,因为我来自Java背景...我正在尝试同时使用Scala语言和该框架。我从语义上了解这里发生的事情,但是从语法上我非常困惑。
我想了解在这里应用了Scala语言中的哪些构造,特别是从对“startServer”的调用以及{}之间的实现开始。这样,我就可以对它进行Google搜索和研究了……但是我不确定在这里查找什么。我认为这可能与语言中的某些功能概念有关。
“startServer”似乎是SimpleRoutingApp的一种方法,但是看起来您正在将嵌套函数传递到它的主体中,即“path”,“get”,“complete” ...这究竟如何工作?感谢您的所有帮助。
最佳答案
Spray不是最容易学习的东西,尤其是当您刚开始使用Scala时,但我会尽力解释。
您需要了解的第一件事是currying。用两个词来说,curried函数是一个返回另一个函数的函数。因此,startServer
是 curry 函数的一个很好的例子,这里是缩短的签名:
def startServer(interface: String, port: Int)(route: ⇒ Route): Future[Http.Bound]
这是声明 curry 函数的一种方法,startServer获取主机和端口,然后“返回”一个函数,该函数获取您的服务
route
并返回Http.Bound
的future。 Scala允许使用的下一个技巧是,您可以在大括号中编写一个argt列表,例如{}
,并且在startServer
中使用它,第一个arg列表包含两个必需的参数,因此您不能使用{}
样式,仅()
,但是当您传递host:port
时,您具有Route => Future[Http.Bound]
函数,因此您可以应用此样式。并且可以进一步应用此规则(path
,get
,complete
)。你里面有什么,即
path("hello") {
get {
complete {
<h1>Say hello to spray</h1>
}
}
}
是您的实际服务Route。它由所谓的directives组成,它们基于HList的无形实现(我不会在这里解释,但是您可以在此处找到信息)。通常,每个指令都是一个对用户HttpRequest(基本上是RequestContext)执行某些操作的函数。可以在here中找到所有指令的描述。
关于Scala Spray Routing语法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24483980/