Scala--控制结构和函数
本篇博客,将介绍scala的:
条件表达式
循环
函数
- 主要是对这些表达式和语句结构的熟悉,需要多练习。在scala中表达式(3+4)和语句(if语句)是不同的概念,
表达式有值,语句执行动作
。 记住
,scala几乎所有构造出来的语法结构都有值。
条件表达式
if/else
的表达式语法和java类似,只是需要注意的是:
- if/else有返回值
- scala代码结尾不需要“;”,除非一行要写多条语句,这个和
Python
类似。下例打印出了if的返回值1,这个小例子就充分说明了if语句是有返回值的。1
2
3
4
5
6
7
8scala> val isTrue=true
isTrue: Boolean = true
scala> if(isTrue) 1 else 0 ##返回值
res0: Int = 1
scala> val f = if(isTrue) 1 else 0 ##返回值
f: Int = 1
if/else表达式的类型推断
,取两个类型的公共父类型,如下String和Int,则表达式的值是Any1
2scala> val f = if(isTrue) "this reture true" else 0
f: Any = this reture true
块语句
- 在scala中“
{}
”包含的一系列表达式,叫做块语句,块中最后一个表达式的值就是块的值
,即块的返回值。下面,定义一个块语句,执行后返回了变量ss的值,ss的值就是块语句中最后一个表达式的值。1
2scala> val ss = { val s1=78; val s2=s1*0.8; s1+s2 }
ss: Double = 140.4
while循环
while循环
,和java的while和do循环相同,这里就不过多讲解了,实例如下图所示。我们定义了一个var变量,然后通过while循环打印出结果,注意scala不支持n++,n- -。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15scala> :paste
// Entering paste mode (ctrl-D to finish)
var n =3
while( n > 0 ) {
n-=1
println(n)
}
// Exiting paste mode, now interpreting.
2
1
0
n: Int = 0注:在”Repl”中写多行代码的时候,每写一行敲一下“回车键”然后它会自动去识别程序是否结束,直到你真正的写完代码,有时候不是很方便;
还有一种粘贴的方法,输入:paste
然后就可以随意的写代码了,写完后Ctrl+D
退出并运行代码,如上图所示。
for循环
for基础
语句结构
:for( i <- 表达式 ) #让变量i遍历<-右边的表达式的所有值,i具体执行取决于表达式
循环体示例1,for循环中的to:
to
:包含上线区间。1
2
3
4
5
6
7
8
9
10
11
12scala> var n = 10; for(i <- 1 to n) println(i)
1
2
3
4
5
6
7
8
9
10
n: Int = 10示例2,for循环中的
until
,until
:返回一个并不包含上线的区间。1
2
3
4
5
6
7
8
9
10
11scala> var n = 10; for(i <- 1 until n) println(i)
1
2
3
4
5
6
7
8
9
n: Int = 10示例3,不使用to和until
1
2scala> for(s <- "blog.xiaoxiaomo.com") print(s+" ")
b l o g . x i a o x i a o m o . c o m
for跳出语句
scala中没有break和continue来退出循环,我们可以这样操作:
- 使用Boolean的变量控制。
- 使用嵌套函数,可以从函数当中return。
- 使用Breaks对象的break方法。
eg:
1
2
3
4
5breakable{
for (...) {
if(...) break ;//#退出breakable块
}
}
for进阶
- 在for循环“()”中可以使用多个生成器, 用“;”隔开;
- 并且每一个生成器都可以带一个
守卫
(if开头的Boolean表达式
); - for推导式,如下示例:
示例1,多个生成器,即多层循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22scala> :paste
// Entering paste mode (ctrl-D to finish)
for(i <- 1 to 9; j <- 1 to 9) {
if(j == 9) {
println(i * j)
} else {
print(i * j + " ")
}
}
// Exiting paste mode, now interpreting.
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81示例2,for循环守卫
1
2
3
4
5
6
7
8
9
10
11scala> for(i <- 1 to 20 if i % 2 == 0) println(i)
2
4
6
8
10
12
14
16
18
20for推导式:如果for循环的循环体以yield开始,该循环就会构造出一个集合,每次迭代就生成一个集合的值。
1
2scala> for( i <- 2 to 8 ) yield i%2
res7: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 0, 1, 0, 1, 0)
函数
基本语法
- 语法如图:
- 函数必须指定
参数的类型
。 - 函数只要不是递归的就不需要指定
返回值类型
(因为无法推断出递归函数的类型)。 - 在函数中,不需要使用return。
1
2
3
4
5
6
7
8
9
10
11scala> def max( x:Int, y:Int ) : Int ={
| if(x>y) x
| else y
| }
max: (x: Int, y: Int)Int
scala> max(78,88)
res8: Int = 88
scala> max(18,99)
res10: Int = 99
函数参数
在函数中,我们可以使用默认参数
。函数调用时:
1、如果没用给出所有参数,函数会使用默认参数(后面不够的参数使用默认值)。
2、也可以指定参数名,参数名不需要按顺序排列。
3、如果混合使用(未名参数和带名参数),只要未名参数排在前面即可。
1
2
3
4
5
6
7
8
9 scala> def defStr( left:String = "[" , str:String , right:String = "]" ) = {
| print( left + str + right )
| }
defStr: (left: String, str: String, right: String)Unit
scala> defStr("[","Hi")
[Hi]
scala> defStr(left="<",right=">",str="xiaoxiaomo")
<xiaoxiaomo>
4、变长参数,可以接受多个参数
1 | def sum(args:Int*) = { |
调用函数,sum(3,4,6,23,3),函数得到的是一个Seq类型的参数,注意调用函数是传入的参数不能是一个区间,eg:
sum(2 to 9)是不可以的,应该为sum(2 to 9:_*);
过程
在scala中,如果函数没有返回值,那么该返回值类型我们可以用
Unit
来表示,这种没有返回值的函数我们称之为过程
。1
2
3
4
5
6
7scala> def pr(s:String){
| print(s)
| }
pr: (s: String)Unit
scala> pr("小小默")
小小默上面省略了Unit,由于没有返回值也可以省略“=”号,下面语句相同:
1
2
3
4
5
6
7scala> def pr(s:String) : Unit = {
| print(s)
| }
pr: (s: String)Unit
scala> pr("小小默")
小小默