控制结构和函数
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=1
if(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<Integer>这种方式。其中“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);
114
scala>
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()
}