Spark大数据实时计算:基于Scala开发实战
上QQ阅读APP看书,第一时间看更新

1.5 Scala控制结构和函数

Scala语言提供了基本的控制结构和丰富的函数。

1.5.1 for表达式

for 表达式的语法格式如下。

for( var x to Range ){
   // 表达式
}
for( var x <- Range ){
   // 表达式
} 

其中,to代表包含数组length。

1.简单循环

我们可以通过.to的方式使用for循环表达式输出数字1~10。

scala> val fun1 = 1.to(10)   // 使用函数.to生成数组
fun1: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)  
  
scala> for(i <-fun1) println(i)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10

我们也可以在for循环中直接使用to输出值。

scala> for(i <- 1 to 10) println(i)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10 

2.嵌套循环

乘法表是嵌套循环的简单示例。

scala> for(i<-1 to 9;j<-1 to i){
     |     print(j+"*"+i+"="+j*i+" ")  
     |     if(j==i)  println()
     | }  
1*1=1   
1*2=2 2*2=4   
1*3=3 2*3=6  3*3=9   
1*4=4 2*4=8  3*4=12 4*4=16   
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25   
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36   
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49   
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64   
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81

3.守卫

在for循环中添加if判断语句作为过滤条件,if判断语句称为守卫。

for(i <- 表达式/数组/集合 if 表达式) {
// 表达式 
}  

比如,循环输出数字1~3,并且过滤掉数字2。

scala> for(i <- 1 to 3 if i != 2) {
     |   print(i + " ")  
     | }  
1 3   

4.for推导式

for推导式主要用来将for循环后的数据返回到一个变量,它区别于Java代码用对象承接的方式,而是使用yield直接将数据返回。

val v = for(i <- Range ) yield 表达式

比如,循环打印数字1~3,并且过滤掉数字2,最后返回到一个变量。

scala> val res = for(i <- 1 to 3 if i != 2) yield {
     |     i  
     | }  
res: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 3) 

1.5.2 while循环

对于while循环,Scala和Java是一样的,比如打印1~10的数字。

scala> var i = 1
i: Int = 1  
  
scala>  while(i <= 10){
     |     println(i)  
     |     i+=1  
     | }  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10

1.5.3 函数

在Scala中,我们可以像操作数字一样将函数赋值给一个变量。

使用val 语句定义函数的方式为:val  函数名 = ([参数名: 参数类型]) => 函数体。

定义两个数相加的函数如下。

scala> val add = (a:Int, b:Int) => a + b
add: (Int, Int) => Int = <function2>  
  
scala> add(1,2)  
res2: Int = 3  

1.5.4 方法和函数的区别

与函数不同,方法需要使用def来定义:def  方法名 (参数名:参数类型,参数名:参数类型):[返回类型] => {方法体}。

函数是对象(变量),而方法不是。方法在运行时,加载到JVM方法区;函数在运行时,加载到JVM堆内存。

函数是对象,继承FunctionN,函数对象有apply、curried、toString、tupled这些方法,方法则没有。方法无法像函数一样赋值给变量。

scala> val f = fun1
<console>:12: error: missing argument list for method fun1
Unapplied methods are only converted to functions when a function type is expected.  
You can make this conversion explicit by writing 'fun1 _' or 'fun1(_,_)' instead of 'fun1'.
       val f = fun1  
               ^ 

想要将方法赋值给一个对象,可以先将方法转换为函数后再进行赋值。

将方法转换成函数的语法格式为val 函数名 = 方法名 _。

scala> val f = fun1 _
f: (Int, Int) => Int = <function2>  
  
scala> def fun1(a:Int,b:Int)= a+b  
fun1: (a: Int, b: Int)Int  
  
scala> val f = fun1 _  
f: (Int, Int) => Int = <function2>