Spark开发指南

控制结构与函数

在java语言中,表达式表示值,语句表示执行动作。 例如:表达式1+1表示值;thread.start()表示执行动作。

所有语法结构都有值,那怕是不存在用Unit类型.

if/else语句

有值,为跟在if或else之后的表达式的值。

例:val s = if(x > 0) 1 else 0;

  等同于var s:Int = 0; if (x > 0) s = 1 else s = 0;

  val s2 = if (x > 0) "string" else 1;

  s2的类型为Any

  val s3 = if (x > 0) 1;

  s3的类型也是Any,但x <= 0时s3的值为Unit, Unit类表示“无有用值”,写做()

没有switch语句

语句终止

一行一条语句,行尾不需要分号

一行多条语句,需要使用分号把它们隔开

较长语句分两行时,在第一行尾部不要用语句结束的符号结束,通常使用一个操作符。如:

  val s = "sssssssssssssssssssssssssss" + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + //告诉解析器这里不是语句的结尾

    "ccc" + "dd"

块表达式和赋值

{}块包含一系列表达式,其结果是块中最后一个表达式的值。

例:val s = {1+2; 2+3} //s的值为5

注意:赋值语句的返回值是Unit类型,写作()

例:val u = {b = 3}

x = y = 1,结果为x的值Unit,y的值1。因为y = 1语句的值为Unit;

输入与输出

print()

println() 打印完后追加一个换行符

printf()具有c风格, %s , %d, %f,

输入:

  readLine("tips"):从控制台读取一行,"tips"为输出提示

  readDouble, readFloat, readByte, readChar readShort, readInt, readLong, readBoolean

循环

while循环

while (n > 0){

  // TODO

}

for循环

for (i <- 1 to n) {

  // TODO

}

for的参数表达式说明:让变量i遍历<-右边表达式的所有值。

通常在遍历时使用util,until返回一个不包括上限的区间。例:0 until 2,表示Range(0, 1)

注:scala没有类似java的for(;;)型for语句

for高级特性:

循环体带yield,即for推导:

  val z = for (i <- 0 until 3) yield i;

  z的值为Vector(0, 1, 2)

多个生成器、守卫、变量定义:

  for (i <- 0 until 5; j <- 3 until ;) { println(i, j)} //多个生成器

  for (i <- 0 until 5; from = 4 - i; j <- from until 5) {} //变量定义

  for (i <- 0 until 5; from = 4 - i; j <- from until 5 if i != j) {} //每个生成器可以带一个守卫,注意if前没有分号

没有break和continue

需要时怎么办?

1、使用变量控制

2、外层嵌套函数,使用return进行break;

3、使用异常机制,抛出异常与捕获异常控制。

scala提供的:

import scala.util.control.Breaks.break
import scala.util.control.Breaks.breakable

breakable {
   for (i <- 0 until 2) {
     println(i)
     if (i == 1) break;
   }
}

函数

定义函数只需要给出函数名、参数和函数体

def 函数名[(参数名:参数类型,…)][: 返回类型]= {

  // function body

}

注:[]表示可选,只要函数不是递归的就不需要指定函数的返回类型;scala会自动推断函数的返回类型。

函数体最后一个表达式的值就是函数的返回值,当然也可以用return显式返回。

如果函数没有参数,括号可以省略,但调用时也不能带括号。

默认参数和带名参数

def test(str: String, left: String = "[", right: String = "]") = left + str + right
test("hello") // 返回[hello]
test("hello", right = ">>")
test("hello", left = "<", right = ">")
test("hello", right = ">")

变长参数:

def sum(args: Int*) = {
 var result: Int = 0
 for (arg <- args) result += arg
 result
}

可以使用合意多的参数来调用该函数

sum(1, 2, 3)

如果有了一个值的序列,不能直接调用,得转化

  val s = sum(1 to 10: *) // *将1 to 10当作参数序列处理。

  val s = sum(1 to 10) // 会报错

此语法的用处是递归

def recursiveSum(args: Int*): Int = {
 if (args.length == 0) 0
 else args.head + recursiveSum(args.tail: _*)
}

args.head表示args的首个元素,而tail表示所有其它的元素。

过程:

没有返回值的函数,函数体前不带“=”。

lazy:

lazy val words = Source.fromFile("readme2.txt").mkString

函数第一次调用时加载

也有额外开销,每次访问懒值,都会调用一个方法以线程安全的方式检查值是否已经初始化

异常

方法不用带类似throw IOException的签名

try{

} catch {

  case : IOException => println("xx") // 不需要使用异常对象,可以使用来代替异常名。

  case e: Exception => e.printStatckTrace()

} finally {

}