换行符
- Scala是面向行的语言,语句可以用分号或换行符结束
- Scala中,如果一行仅有一个语句,末尾的分号通常是可选的
统一类型

- Scala中没有所谓的基本数据类型,一切皆对象,所有的数据类型都是以对象形式存在,函数也是一种对象
- Any是所有类型的超类型,定义了一些通用的方法:equals和hashCode等,Any有两个直接子类:AnyVal、AnyRef
- AnyVal代表值类型,其中Unit是不带任何意义的类型,在函数返回时,可以以Unit作为返回类型
- AnyRef代表引用类型,所有非值类型都被定义为引用类型,用户声明的自定义类型都属于AnyRef的子类型
- Java运行环境调用Scala,AnyRef会被当做Object基类
- Nothing是所有类型的子类型,包括值类型和引用类型,Nothing也是Null的子类型,也被称为底部类型
- 没有一个值是Nothing类型的,Nothing类型通常用于程序非正常结束的信号
- 这与Java中返回null类似,可以将Nothing理解为不定义值的表达类型,在非正常返回时使用
- Null是所有引用类型的子类型,它有一个单例值由关键字Null所定义
- Null主要是使得Scala满足和其他JVM语言的互操作性
- 但是Null是非常容易引发程序崩溃的类型,Scala代码中采用了各种机制来避免使用Null类型
1 | val list: List[Any] = List("a string", 732, 'c', true, () => "func") |
变量 + 常量
- 在程序运行过程中值可能改变的量称为变量,不会发生变化的量称为常量
- 声明变量关键字var,声明常量关键字val
1 | var myVar: String = "Spark Action" |
条件 + 循环
- Scala不支持break和continue语句
- 多数情况下,break和continue不是必要的,可以用小函数更好地解决
- 在循环中使用continue是非常容易理解的,但在Scala的函数闭包中是难以理解的
- 如果巧妙地使用函数字面量代替continue和break,可以使代码更加精简
- 可以用纯库函数的形式提供对两者的支持
- 从Scala 2.8之后,可以通过
scala.util.control.Breaks._
库来使用break操作 - 对于continue,Scala原生库还是没有提供支持,可以通过
scala.util.control.Breaks._
来实现
1 | import util.control.Breaks._ |
1 | import scala.util.control.Breaks._ |
函数 + 方法
- 在Scala中,一切皆对象,函数在Scala中也是一个对象,借用函数式编程的思想,函数可以作为参数传递给另一个函数
- 在Java中,方法和函数并没有区别,但在Scala中,Method被翻译成方法,Function被翻译成函数
- Scala Method:类中定义的方法,属于类的一部分,与Java的方法类似
- Scala Function:代表一个对象,可以像值类型一样赋值给一个变量
- Function是一个完整的对象,本质上是继承了Trait的类的对象
- Function是一个对象,可以作为参数传入到方法中,而Method不行
- Scala中使用def语句定义方法,使用val语句定义函数
- 可以在方法名称后面紧跟一个空格加下划线,将方法转换为函数,通常编译器会自动完成该操作
- 例如将一个方法传入接收函数参数的地方,就会自动转换
- 函数和方法是可以相互转换的
1 | abstract class FunctionMethodTests { |
函数式编程
可变参数列表
可变参数列表是指在定义方法时,不需要指定函数参数的个数,而在函数被调用时灵活传入,如同传入一个变长数组
1 | def main(args: Array[String]): Unit = { |
默认参数值
Java不支持默认参数值,而Scala支持
1 | object Test2 { |
偏应用函数
偏应用函数指的是固定方法的某一个参数,然后重新声明为一个函数,这是Scala提供的语法糖
1 | def main(args: Array[String]): Unit = { |
指定函数参数名
在Java或C++中,调用函数时只能按照函数定义时指定的顺序将参数传入,而Scala和Python支持指定参数名
1 | def main(args: Array[String]): Unit = { |
高级函数
- 高阶函数指的是操作其他函数的函数
- 在Scala中,可以将函数作为参数来传递或者通过运算返回一个函数的引用,这种函数就是高阶函数
- 在Java 8引入了Lambda表达式,也支持这种特性
1 | def main(args: Array[String]): Unit = { |
函数柯里化
- 函数柯里化是函数式编程中的一个概念
- 函数柯里化
- 将原来接收两个参数的函数,变成新的接收一个参数的函数
- 新的函数返回一个以第二个参数为参数的函数
- Scala支持函数柯里化
1 | def main(args: Array[String]): Unit = { |
特质、单例和样例类
特质
- 特质(Traits)用于在类(Class)之间共享程序接口(Interface)和字段(Field)
- 是Scala独有的一种特性,类似于Java 8的接口
- 类和对象(Objects)可以扩展特质,但特质不能被实例化,因为特质没有参数
1 | trait Iterator[A] { |
混入
当某个特质被用于组合类时,被称为混入
1 | abstract class A { |
单例
Scala在语言特性中提供单例的支持,即object关键字
1 | object Logger { |
伴生对象
将类和object放在同一个文件中,形成伴生对象
1 | import scala.math._ |
样例类
- 在Java中,有一种类只有get/set方法,在网站开发和数据库绑定的DAO设计模式中比较常见
- Scala将这种特殊的类内化在语言特性中,即样例类,经常与模式匹配结合使用
1 | case class Book(isbn: String) |