运算符带了双引号,这是因为从技术上来说,Scala 并没有所谓的“运算符”,在这里是指重载符号,如+ ,+- 等等。
在 Scala 中,事实上这些是方法的名字。但是由于 Scala 并不需要点来分隔对象引用和方法名,因而看起来像是运算符。调用 ref1+ref2 其实与 ref1.+(ref2)是等同的,调用的其实是 ref1 的+()方法。
举例如下:
class Complex(val real: Int, val imaginary: Int) {
def +(operand: Complex) : Complex = {
new Complex(real + operand.real, imaginary + operand.imaginary)
}
override def toString() : String = {
real + (if (imaginary < 0) "" else "+") + imaginary + "i"
}
}
val c1 = new Complex(1, 2)
val c2 = new Complex(2, -3)
val sum = c1 + c2
println("(" + c1 + ") + (" + c2 + ") = " + sum)
运行结果:
(1+2i) + (2-3i) = 3-1i
再次强调,Scala 并不存在运算符,所以没有定义运算符优先级,但是同时又定义了方法的优先级。方法的第一个字符用来决定它们的优先级,如果两个同等优先级的字符在同个表达式中出现,那左边的优先。
Read more…
函数和交互式应用程序
回调(callback)在交互式应用程序中是很常见的。例如一个按钮被点击,并进行一个特定的动作。在Web 应用程序中创建回调是尤其困难的,除非你拥有像Scala这样强大的工具。下面创建一个方法,它生成一个随机的String,以作为一个全局唯一的标识符(GUID)。
scala> def randomName() = "I"+ scala.util.Random.nextLong.abs
randomName: ()java.lang.String
然后定义一个通用的JavaScript trait, 我们不需要刷新它,假设它包含可以在浏览器中运行的JavaScript 命令。
scala> trait JavaScript
defined trait JavaScript
下面用一个能生成 JavaScript的函数来创建一个Map 以关联GUID:
scala> var callbacks: Map[String, () => JavaScript] = Map()
callbacks: Map[String,() => JavaScript] = Map()
scala> def register(f: () => JavaScript) = {
| val name = randomName
| callbacks += name -> f
| <button onclick={"invokeServerCall("""+name+""")"}>ClickMe</button>
| }
register: (f: () => JavaScript)scala.xml.Elem
当用户点击按钮时,会用 GUID 创建一个Ajax HTTP 请求,Servlet 在map中查找GUID,如果GUID存在,这个函数就会被调用并将JavaScript则返回给浏览器,这个功能的代码类型于:
Scala> def handleAjax(guid: String): HttpResponse =
functionMap.get(guid).map(f => f()) match {
case Some(javaScript) => JavaScriptResponse(javaScript)
case _ => Http404Response()
}
上面的代码是 Lift 框架的简化版本,可以看到,这种写法可以让程序员更关注于业务逻辑。
Read more…
评论