控制结构和函数
1.关于返回值 在scala任何的函数、表达式、方法都有返回值(有些情况类似与java的void,所以scala创立了unit这个标识符来表示特殊的返回值)。 (1){}的返回值以其中最后一个表达式的返回值为准,eg:
{val r=1;r+1},该表达式的返回值就是2,因为r+1的返回值为2; (2)赋值表达式的返回值为unit,eg: val k=5,该表达式的值为unit的形式; 注意:在给变量赋值的时候,注意负数的书写: var t=-1 ,这种写法可能会报错,必须将负数符号与等号加一个空格。
2.选择表达式的值(1)Scala 包含 if/else 的结构 与 Java 或 C++中的相同。但是在scala中if/else表达式是有值的——称为if或else表达式的值。例如:val test=1if(test>0) 1 else -1语句运行后,输出:res14: Int = 1其中,1就是这个表达式的值,你可以将这个值赋予其它的变量: val s = if (x > 0) 1 else -1,当然也可以写成:if (x > 0)s= 1 else s=-1,但是第一种写法比较好,因为第一种写法可以用来初始化val类型的变量, 而第二种方法中的s只能是var类型的。同时在java中有一个式子和它的功能相同:x > 0 ? 1 : -1; (2)在scala中每个表达式都有它们的类型, if (x > 0) 1 else -1表达式的类型就是Int,当然if/else表达式也有混合值,比如: if (x > 0) 1 else“good”; 但是它们的返回值有意个共同的超类:Any。也就是Any相当于万金油,类似于java中的Objetc。如果表达式缺少了else,它怎样取值呢?在scala中,表达式总是要有一个值的,面对这个情况,scala创造了unit类型,这类似与java中的 voido类型,所以 if (x > 0) 1 可能会返回unit。 3.输入与输出 scala中常用的输出为: print("hello ")或println(2),只要对java多少有点了解的人都知道,这里跟java中的相似,就是少了System.out; 另外还可一写成C++中的方式:printf()等。 4.循环 (1)常用循环 java中的循环语句scala中while关键字可以直接拿过来用,要注意的是,scala不支持传统的for循环。但是要想更好地学习scala,理解函数 式编程,就要学会scala中特有的循环方式: for (i <- 1 to n) r = r * i 下面为大家介绍该语句的原理:
1 to n 为 1.to(n),该语句返回一个集合,该集合包含1到n之间的所有整数,优点类似与arraylist这种方式。其中“1 to n”也可写 成1 untils n+1的方式,都是返回1到n之间的所有整数集合。另外,只要是集合类型都可以用于该方法中,eg: var sum = 0 for (ch <- "Hello") sum += ch "Hello"在这里被认为字符集合。 补充: (2)双重循环 双重循环可以使用java中循环叠加的方式实现,也可使用如下方式实现: for (i <- 1 to 3; j <- 1 to 3) print((10 * i + j) + " ") // Prints 11 12 13 21 22 23 31 32 33 在循环体中,还可以嵌套处理语句 for (i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ") // Prints 12 13 21 23 31 32 或 for (i <- 1 to 3; from = 4 - i; j <- from to 3) print((10 * i + j) + " ") // Prints 13 22 23 31 32 33 for与yeild循环 for (i <- 1 to 10) yield i % 3 // 返回 Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1) 加入yeild关键字,会返回一组集合类型,这种形式的循环被称作for 理解。 (3)跳出循环 在scala中,并不提供break或continue等语句,如果要跳出循环,有以下语句: 1. 使用一个布尔控制变量代替——while循环中 2. 使用return 3. 使用Breaks对象中的break方法: import scala.util.control.Breaks._ breakable { for (...) { if (...) break; // Exits the breakable block ... } } 注意:在scala常常避免使用for循环(这是for循环在scala中的实现形式决定的),会采用其它方式;另外for循环和while循环的性能差距比较大
scala> var start = System.currentTimeMillis(); var total = 0;for(i <- 0 until 100000) { total += i }; var end = System.currentTimeMillis(); println(end-start); println(total);114scala>scala< var start = System.currentTimeMillis(); var total = 0;var i=0;while(i < 100000) { i=i+1;total += i }; var end = System.currentTimeMillis(); println(end-start); println(total);8
5.函数 除了方法外,scala还具有函数元素;scala与java的方法要通过类的对象来调用,在java中要实现函数的功能就要依附于类而存在。我们说过 在scala的世界中,函数也是对象,而且是这个世界的一等公民,所以函数定义后可以像对象那样使用,eg: def abs(x: Double) = if (x >= 0) x else -x 你必须指定所有参数的类型. 如果函数不是递归的(程序调用自身的编程技巧称为递归,递归函数必须要有返回值,并知道返回值的类型),所以你不 必规定返回类型,scala编译器从等号右边的表达式来决定返回值的类型; 如果函数比较复杂,则使用块来标识函数,eg: def fac(n : Int) = { var r = 1 for (i <- 1 to n) r = r * i r },函数的返回值就是块的返回值;上面代码的返回值为r,因为块的最后一句是r,r的返回值就是r的值本身; 对于递归函数,必须规定返回值,eg: def fac(n: Int): Int = if (n <= 0) 1 else n * fac(n - 1) scala中函数与方法的区别 是否带等号的就是函数,不带等号的就是方法? 否,函数若没有返回值可以不写等号; 6.方法 7.慵懒变量 如果在val类型的变量前面加入lazy标识符,则改变量的初始化就会放在使用它的时候,这样可以在初期的初始化过程中,节省时间,方便系统的启动 ,在另一种意义上说这是一种负载均衡,eg: lazy val words =“word”,只有在使用时,words才会被真正赋值; 8.异常 在scala中,异常的定义与java中相似,不过抛出异常操作的类型为nothing,捕获异常处理使用特殊的模式匹配语法: try { process(new URL("http://horstmann.com/fred-tiny.gif")) } catch { case _: MalformedURLException => println("Bad URL: " + url) case ex: IOException => ex.printStackTrace() }