Scala笔记

语言特性

Scala 是 Scalable Language 的简写,是一门多范式的编程语言。

面向对象特性
Scala是一种纯面向对象的语言,每个值都是对象。对象的数据类型以及行为由类和特质描述。
类抽象机制的扩展有两种途径:一种途径是子类继承,另一种途径是灵活的混入机制。这两种途径能避免多重继承的种种问题。

函数式编程
Scala也是一种函数式语言,其函数也能当成值来使用。Scala提供了轻量级的语法用以定义匿名函数,支持高阶函数,允许嵌套多层函数,并支持柯里化。Scala的case class及其内置的模式匹配相当于函数式编程语言中常用的代数类型。
更进一步,程序员可以利用Scala的模式匹配,编写类似正则表达式的代码处理XML数据。

静态类型
Scala具备类型系统,通过编译时检查,保证代码的安全性和一致性。类型系统具体支持以下特性:

  • 泛型类
  • 协变和逆变
  • 标注
  • 类型参数的上下限约束
  • 把类别和抽象类型作为对象成员
  • 复合类型
  • 引用自己时显式指定类型
  • 视图
  • 多态方法

数据类型

有符号补码整形:Byte、Short、Int、Long
浮点数:Float、Double
字符形:Char、String
布尔:Boolean
空:Unit、Null、Nothing
父类:Any、AnyRef

1
2
3
4
var a = 2147483648; //失败,字面值必须是Int范围?能否强制类型装换?

var a:Long = 2147483647
a = a+1 // 成功

函数

scala的函数比体现了函数是语言的特点。由于我写python比较多,这里和python的函数式特点进行对比。

函数声明

scala是静态类型,强制要求函数提供参数与返回值类型,python是动态类型,可以提供相关类型信息,不过只是作为函数注解(annotation),不知道是不是函数是语言的风格,类型说明的语法上两者还是很像的。
执行的时候,scala会进行类型检查与可能得类型转换,python则不会。

  • scala

    1
    2
    3
    4
    5
    6
    def add(a:Int, b:Int):Int = {
    return a+b
    }
    println(add(1,2))
    println(add('a','b'))
    println(add(1.1,1.2))
  • python

    1
    2
    3
    4
    5
    def add(a:int, b:int) -> int:
    return a+b
    print(add(1,2))
    print(add('a','b'))
    print(add(1.1,1.2))

函数传名调用

Scala的解释器在解析函数参数(function arguments)时有两种方式:

  • 传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部;
  • 传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部

在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。

这就造成了一种现象,每次使用传名调用时,解释器都会计算一次表达式的值。
python不细说。

  • scala:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    def showTime() = {
    println(System.nanoTime)
    }
    def add(a:Int, b:Int):Int = {
    a+b
    }
    def decorate1(f:()=>Unit) = {
    println("something")
    f()
    }
    def decorate2(f:(Int,Int)=>Int, a:Int, b:Int):Int = {
    println("something")
    f()
    }
    decorate1(showTime)
    decorate2(add,1,2)
    # 模仿python装饰器
    def decorator(f:()=>Unit):(()=>Unit) = {
    def caller()={
    println("inner")
    f()
    }
    return caller
    }
    f = decorator(showTime)
    f()

指定函数参数名

要说的不多

可变参数列表

Scala 允许你指明函数的最后一个参数可以是重复的,即我们不需要指定函数参数的个数,可以向函数传入可变长度参数列表。

Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)。

  • scala:

    1
    2
    3
    4
    5
    6
    7
    8
    def printStrings( args:String* ) = {
    var i : Int = 0;
    for( arg <- args ){
    println("Arg value[" + i + "] = " + arg );
    i = i + 1;
    }
    }
    printStrings("A","B")
  • python

    1
    2
    3
    def printStrings(*arg):
    for i, s in enumerate(arg):
    print("Arg value[{}] : {}".format(i, s))

递归函数

  • scala
    1
    2
    3
    4
    5
    6
    7
    def factorial(n: BigInt): BigInt = {  
    if (n <= 1)
    1
    else
    n * factorial(n - 1)
    }
    factorial(5)

默认参数值

  • scala
    1
    2
    3
    4
    def addInt( a:Int=5, b:Int=7 ) : Int = {
    a + b
    }
    addInt()

高阶函数

高阶函数(Higher-Order Function)就是操作其他函数的函数。
Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果。

局部函数

1
var add = (a:Int, b:Int) => a+b

偏函数与柯里化

1
2
3
4
5
6
7
//偏函数
inc = add(1,_)
//柯里化
def add(a:Int)(b:Int) : Int = {
a+b
}
println(add(1)(2))
本站总访问量