使用 Scala
在 Scala 中,使用
:load
指令编译并运行文件。[P10]Scala 脚本通过将其封装到匿名对象中以供编译。[P10]
使用
scalac -Xscript
指令将脚本文件编译为 JVM 字节码。[P10]Scala 使用
[]
标记参数类型,Java 使用<>
。[P11]在函数式变成中,值和函数是高度对齐的。[P11]
Java 8 之前实现 Lambda 的方法:借助接口,在接口中定义一个匿名内部类,并在内部类中声明执行真正工作的方法。[P11]
Scala 中使用
=>
声明 Lambda 。[P11]在 Scala 中,函数或方法中把最后一条表达式的返回值作为自己的返回值。
return
关键字只能在方法中使用,在匿名函数中不允许使用。[P11]对于大多数 OOP Language ,方法指的是类或者对象中定义的函数,方法中的
this
引用会隐性地指向某一对象。Scala 不支持静态类型。Scala 使用
object
声明单例对象。[P12][�补充:Singleton Implementation: Scala]-
接收单一参数的函数 / 方法中可以使用
_
占位符。[P14]strings.map(s: String) => s.toUpperCase()) // 等价于 strings.map(_.toUpperCase())
args.map(_.toUpperCase()).foreach(printf("%s", _))
Predef
定义了 Scala 自动加载的方法和类型。API Doc[P15]使用
scala -cp
将当前目录添加到查询类路径中。在 SBT 提示符下,可以使用
run-main
直接运行指定程序。[16]
并发
在 actor 并发模型中,actor 是独立的软件实体,它们之间不共享任何可变状态信息,而是通过交换消息的方式通信,以此消除同步访问共享可变状态的操作。[P17]
声明了
case
关键字的类,构造函数的参数都会自动转化为只读字段。[P18]case
关键字会让编译器自动生成许多方法,比如类似 Java 的String
、equals
和hashCode
。[P19]编译器会为 case 类生成一个伴生对象( companion object )�,伴生对象是一个与 case 类同名的单例对象。[P19]
Scala 允许自己定义伴生对象,只要对象名和类名相同并且在同一个文件中,这些对象就能称作伴生对象。[P19]
-
apply
方法也是伴生对象中自动添加的方法之一:[P19]val p1 = Point.apply(1.0, 2.0) // 等价于 val p2 = Point(1.0, 2.0)
自定义的伴生对象必须包含
apply
方法。[P20]伴生对象的
apply
方法可以用于决定相对复杂的类继承结构。[P20]在类而不是对象中定义的
apply
方法适用于该类的实例。返回 Unit 的函数一定有副作用。[P20]
-
高阶函数:接收其他函数参数并返回函数的函数。[P21]
def draw(f: String => Unit) : Unit = f(s"draw: ${this.toString}
actor 系统中,每一个 actor 都会有一个关联邮箱( mailbox ),关联邮箱中存储着大量消息,这些消息要经过 actor 处理后才会被提取。Akka 确保了消息处理的顺序与接受顺序相同,而对于那些正在被处理的消息,Akka 保证不会有其他线程抢占该消息。因此其线程安全。[P22]
偏函数 PartialFunction ,接收单一的
Any
类型参数并返回Unit
值。偏函数的函数体一定会产生副作用。[P22]�由于 actor 系统采用了异步消息机制,它必须依靠副作用。[P22]
Akka actor 的偏函数仅包含一些
case
子句,对传递给函数的消息执行模式进行匹配。[P23]在 Akka 中,代码
sender ! Response("")
创建了回复信息,并发送该信息给发送方。Actor.send
返回了 actor 发送消息接收方的对象引用,而!
方法用于发送异步消息。函数式编程中的模式匹配与面向对象编程中的子类型多态是两种编程环境下对类型匹配的不同实现。[P24 - 25]