【Scala】基础2:表达式和循环控制语句

表达式

表达式是返回一个值的代码单元,表达式的关键就是要返回捕获和使用的值。

之前我们定义值和变量是都赋为字面量值,更准确的说法是将他们赋为表达式的返回值,而不论表达式是字面量、计算式还是函数调用。

表达式块

可以使用大括号结合多个表达式创建一个表达式块,表达式有自己的作用域,可以包含表达式块中的局部值和变量。

块中的最后一个表达式将作为整个表达式块的返回值

表达式块也可以嵌套,每一级表达式块都有自己的值和变量。

{
    val a = 1;      
    {        
        val b = a * 2;        
        {          
            val c = b + 4; 
            c        
        }
    }    
}

if表达式

可以根据一个表达式的解析结果(truefalse)选择一个代码分支。

使用if块作为表达式的问题在于:它们只能有条件地返回一个值。如果布尔表达式返回false,你认为if块会返回什么?

举例:val result = if(false) "what does this return?“

——这个例子中结果值的类型未指定,可能会返回一个StringUnit,所以编译器会选择根类Any。这是String(扩展了AnyRef)和Unit(扩展了AnyVal)共同的根类。

if...else表达式

举例: 

val x = 10;

val y = 20

val max = if(x>y) x else y

如果if...else表达式不能很容易地放在一行上,就应该考虑使用表达式块,这样代码会更可读。

匹配表达式match

类似CJava的“Switch”语句,首先会计算一个输入项,并执行第一个“匹配”模式,然后返回它的值。

举例:上面的例子,不同的实现方式 

val x = 10;

val y = 20
  
val max = x > y match{
    
    case true => x 
    
    case false => y
  
}

一个case块中的语句和表达式个数没有任何限制,只是最后一个表达式会用作匹配表达式的返回值。

val status = 500
val message = status match {
    case 200 => "OK"
    case 404 => {
        println("ERROR - we called the service incorrectly")
        "error"
    }
    case 500 => {
        println("ERROR - the service encountered an error")
        "error"
    }
}

多个模式重用相同的case块,可以使用模式替换避免重复的代码。

val day = "MON"
val kind = day match{
    case "MON"|"TUE"|"WED"|"THU"|"FRI" => "weekday"
    case "SAT"|"SUN" => "weekend "
}

如果找不到与数据表达式匹配的模式,会发生什么?

例如:"match me" match {case "match" => "sorry"} ——会报scala.MatchError错误

为了避免错误破坏匹配表达式,可以使用一个通配的“全匹配”模式。将通配模式作为最后一个模式放在匹配表达式中,这会匹配所有可能

得输入模式,从而避免scala.MatchError

全匹配的两种办法:

①值绑定:利用值绑定或变量绑定,将把匹配表达式的输入绑定到一个局部值,然后可以在case块的体中使用。由于模式包含所绑定的值名,并没有要匹配的具体模式,因此值绑定是一个通配模式,他能匹配任何输入值。

val message = "OK"
val status = message match{
    case "OK" => 200
    case other => {
        println(s"Count't parse $other")
        -1
    }
}

②通配符:通配符是一个下划线(_)字符,相当于一个匿名占位符,最后将在运行时替换为一个表达式的值。与值绑定类似,下划线通配符没有提供可以匹配的具体模式,因此这是一个通配模式,也可以匹配任何输入值。

val message = "Unauthorized"
val status = message match{
    case  "OK" => 200
    case  _ => {
        println(s"Count't parse $message")
        -1
    }
}

匹配表达式+if表达式

val response:String = null
response match{
    case s if s !=null => println(s"Received '$s'")
	case s => println("Error! Receive a null response")
}

语句

语句就是不返回值的表达式。

语句的返回类型为Unit,这种类型指示没有值。

循环控制语句

for循环

在Java中循环经常会用到数值递增/递减,例如for(int i = 0, i < 10, i++)

而scala中语法结构为for(临时变量 <- 迭代对象)

举例:

for (i <- 1 to 10)    //从1到10增序

for (i <- 1 to 10 reverse)    //从10到1降序

for (i <- Range(1,10))    //从1到9(不包括10),默认步长为1,增序

for (i <- Range(10,1,-1))    //从10到2(不包括1),降序

yield关键字

如果表达式中指定了yield这个关键字,调用的所有表达式的返回值将作为一个集合返回。

val days = for (x <- 1 to 7) yield {
    x
}
println(days)
for (x <- days){
    println(x)
}

还可以为迭代器增加一个if表达式。使用迭代器哨卫时,可以跳过一次迭代,除非if表达式返回true。

val threes = for(i <- 1 to 20 if i%3 ==0) yield {
    "h"+i
}
for (j <- threes){
    println(j)
}
==========================================================================================================================
val strs = "Faith,Hope,,Charity"
for{
    t <- strs.split(",")
    if t != null
    if t.size>0
}
{
    println(t)
}

嵌套迭代器(就是多重for循环啦

①原来的方式

for(x <- Range(1,3)){
    for(y <- Range(2,4)){
        println(s"$x,$y")
    }
}

②使用嵌套迭代器

for{x <- Range(1,3);y <- Range(2,4)}
{
    println(s"$x,$y")
}

如果for循环使用小括号,最后一个迭代器之前的各个迭代器行必须以一个分号结尾。

对于使用大括号的for循环,迭代器行末尾的分号则是可选的,在同一行时需要使用分号分割。

while循环和do-while循环

二者语法同Java完全相同,这里就不再赘述

猜你喜欢

转载自blog.csdn.net/hr786250678/article/details/86297259
今日推荐