Scala语法要点记录

Scala语法和Java相似度比较高,这里列出差异较大的部分备忘。以下所使用Scala版本为2.11.8。

基本语法

Scala里语句结尾的分号不是必须的。

在 Scala 中,使用关键词 "var" 声明变量,使用关键词 "val" 声明常量。

private[x] ,读作"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。

Scala 使用 Option[String] 来告诉你:“我会想办法回传一个 String,但也可能没有String 给你”。Option 有两个子类别,一个是 Some,一个是 None。

数组

声明数组的方式:

var z1 = new Array[String](3)
var z2 = Array("Runoob", "Baidu", "Google")
var z3 = Array.ofDim[Int](3,5) //二维数组:三个一维数组,每个数组有五个元素

访问数组元素(第一个元素下标是0):

z1(0)

遍历数组中的元素:

for ( x <- z1){
    println(x)
}

集合

Scala提供与Java相似的List、Set和Map:

// 定义整型 List
val x = List(1,2,3,4)

// 定义 Set
var x = Set(1,3,5,7)

// 定义 Map
val x = Map("one" -> 1, "two" -> 2, "three" -> 3)

用三冒号(:::)连接两个List:

scala> List(1,2,3) ::: List(4,5)
res2: List[Int] = List(1, 2, 3, 4, 5)

双冒号(::)连接一个元素和一个List(注意元素必须在左侧,原因是以冒号结尾的方法名会被方法的右操作参数调用,其他时候是被左操作参数调用):

scala> 3 :: List(4,5)
res3: List[Int] = List(3, 4, 5)

也可以用 +: 或 :+ 连接一个元素和一个List,取决于元素在左侧或右侧(元素必须在 + 所在的那一侧):

scala> 2 +: List(1,3)
res39: List[Int] = List(2, 1, 3)

在Scala里定义一个List有多种方法,比如直接枚举所有元素:

scala> List(5,8,9,12,20)
res23: List[Int] = List(5, 8, 9, 12, 20)

还可以指定一个范围:

scala> List.range(1,10)
res24: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

更多方法参考Five ways to create a Scala List

Scala的元组:

val t = (1, 3.14, "Fred") 
val t = new Tuple3(1, 3.14, "Fred")

上面两个语句是等价的,Scala支持元组长度最大为22。

遍历元组:

t.productIterator.foreach{ i =>println("Value = " + i )}

 

迭代器:

val it = Iterator("Baidu", "Google", "Taobao")
while (it.hasNext){
    println(it.next())
}

函数

定义一个函数(如果函数没有返回值,可以返回Unit):

def addInt( a:Int, b:Int ) : Int = {
    return a+b
}

高阶函数(使用其他函数作为参数的函数):

def apply(f: Int => String, v: Int) = f(v)

匿名函数(用def、val定义也可以):

var inc = (x:Int) => x+1

相当于

def inc(x:Int):Int={
    return x+1
}

函数柯里化:

柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。

def add(x:Int)(y:Int) = x + y

闭包

带有“自由变量”的函数称为闭包,例如:

val more = 3 //如果没有定义这个变量,下面一行语句会报错
val addMore = (x: Int) => x + more

上面的定义里,more是一个自由变量,因此这个函数不是封闭的。

下面这样定义也是合法的:

def makeIncreaser(more: Int) = (x: Int) => x + more

定义一个类(类里包含变量和函数):

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点: " + x);
      println ("y 的坐标点: " + y);
   }
}

类的继承:

class Location(override val xc: Int, override val yc: Int, val zc :Int) extends Point(xc, yc){
   var z: Int = zc

   def move(dx: Int, dy: Int, dz: Int) {
      x = x + dx
      y = y + dy
      z = z + dz
      println ("x 的坐标点 : " + x);
      println ("y 的坐标点 : " + y);
      println ("z 的坐标点 : " + z);
   }
   
   //重写一个非抽象方法(例如toString)时必须使用override修饰符。
   override def toString = super.toString + "in my subclass"
}

单例:Scala里没有static关键字,要实现单例可以用object代替class定义对象。

伴生对象:用object定义的对象名与class定义的类名相同,object定义的对象可以访问class里定义的属性和方法。

特征(Trait)

Trait的角色类似Java里的抽象类(可以定义变量和方法实现),class可以继承多个trait。

trait Equal {
  def isEqual(x: Any): Boolean //抽象方法
  def isNotEqual(x: Any): Boolean = !isEqual(x) //带实现的方法
}

 

参考资料: