Cris 的 Scala 笔记(五):流程控制

5. 流程控制

5.1 分支控制

单分支

if (条件表达式) {

​ 执行代码块

}

说明:当条件表达式为ture 时,就会执行 { } 的代码

双分支

if (条件表达式) {

​ 执行代码块1

​ } else {

​ 执行代码块2

}

多分支

if (条件表达式1) {

​ 执行代码块1

​ }

​ else if (条件表达式2) {

​ 执行代码块2

​ }

​ ……

​ else {

​ 执行代码块n

​ }

分支控制if-else 注意事项
  1. 如果大括号{}内的逻辑代码只有一行,大括号可以省略, 这点和java 的规定一样。

  2. Scala中任意表达式都是有返回值的,也就意味着if else表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容

  3. Scala中是没有三元运算符,但是可以这样写 var result = if(a>0)“a” else “b”

  4. 在scala中没有switch,而是使用模式匹配来处理

小练习:

求二元一次方程组的解(ax^2+bx+c=0)

def main(args: Array[String]): Unit = {

  println("请输入a:")
  val a = StdIn.readInt()
  println("请输入b:")
  val b = StdIn.readInt()
  println("请输入c:")
  val c = StdIn.readInt()

  val d = math.pow(b, 2) - 4 * a * c

  if (d > 0) {
    val x1 = (-b + math.sqrt(b * b - 4 * a * c)) / (2 * a)
    var x2 = (-b - math.sqrt(b * b - 4 * a * c)) / (2 * a)
    println(x1.formatted("%.2f") + "," + x2.formatted("%.2f"))
  } else if (d == 0) {
    val x = (-b + math.sqrt(b * b - 4 * a * c)) / (2 * a)
    println(x)
  } else {
    println("无解")
  }

}

5.2 for循环控制

Scala 也为for 循环这一常见的控制结构提供了非常多的特性,这些for 循环的特性被称为for 推导式(for comprehension)或for 表达式(for expression)

范围数据循环方式1

for(i <- 1 to 3){

print(i + " ")

}

  1. i 表示循环的变量, <- 规定 to 规定

  2. i 将会从 1-3 循环, 前后闭合

范围数据循环方式2

for(i <- 1 until 3) {

print(i + " ")

}

  1. 这种方式和前面的区别在于 i 是从1 到 3-1

  2. 前闭合后开的范围

循环守卫

for(i <- 1 to 3 if i != 2) {

print(i + " ")

}

循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为true则进入循环体内部,为false则跳过,类似于continue

上面的代码等价

for (i <- 1 to 3){
	if (i != 2) {
		print(i + "")
	}
引入变量

for(i <- 1 to 3; j = 4 - i) {

print(j + " ")

}

  1. 没有关键字,所以范围后一定要加;来隔断逻辑

  2. 上面的代码等价

for (i <- 1 to 4) {
  val j = i + 1
  println(j)
}

还有另外一种写法

for {
  i <- 1.to(2)
  j = i + 2} {
  println(i + "****" + j)
}
嵌套循环
for (i <- 1.to(3); j <- 1 to 2) {
  println(s"i=${i},j=${j}")
}
  1. 没有关键字,所以范围后一定要加;来隔断逻辑

  2. 上面的代码等价

for (i <- 1.to(3)) {
  for (j <- 1 to 2) {
    println(i + "--" + j)
  }
}

练习:打印九九乘法表

/*打印九九乘法表*/
for (i <- 1.to(9); j <- 1 to i){
  print(i+"*"+j+"="+(i*j)+"\t")
  if (i == j){
    println()
  }
}
循环返回值
val ints = for (i <- 1.to(3)) yield i * 2
println(ints) // Vector(2, 4, 6)

将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字

细节注意
  1. scala 的for循环形式和java是较大差异,这点请同学们注意,但是基本的原理还是一样的。

  2. scala 的for循环是表达式,是有返回值的。java的for循环不是表达式,没有返回值.

  3. scala 的for循环的步长如何控制! [for(i <- Range(1,3,2)]

    /*右闭*/
    for (i <- 1.to(5, 2)) {
      println(i)
    }

    /*右开*/
    for (i <- Range.apply(1, 5, 2)) {
      println("===" + i)
    }

5.3 while 循环

while 循环

循环变量初始化

while (循环条件) {

​ 循环体(语句)

​ 循环变量迭代

}

  1. 循环条件是返回一个布尔值的表达式

  2. while循环是先判断再执行语句

  3. 与If语句不同,While语句本身没有值,即整个While语句的结果是Unit类型的()

  4. 因为while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量 ,而变量需要声明在while循环的外部,那么就等同于循环的内部对外部的变量造成了影响, 也就违背了函数式编程的重要思想(纯函数思想),所以不推荐使用,而是推荐使用for循环

do…while 循环
  1. 循环条件是返回一个布尔值的表达式

  2. do…while循环是先执行,再判断

  3. 和while 一样,因为do…while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量 ,而变量需要声明在do…while循环的外部,那么就等同于循环的内部对外部的变量造成了影响, 也就违背了函数式编程的重要思想(纯函数思想),所以不推荐使用,而是推荐使用for循环

/*while 循环*/
var i = 1
while (i < 2) {
  println(i)
  i += 1
}

/*do while 循环*/
do {
  println("*" + i)
  i += 1
} while (i < 4)

5.4 多重循环

介绍

  1. 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while均可以作为外层循环和内层循环。【建议一般使用两层,最多不要超过3层

  2. 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。

  3. 设外层循环次数为m次,内层为n次, 则内层循环体实际上需要执行m*n=mn次。

5.5 循环中断(重点)

Scala内置控制结构特地去掉了break和continue,是为了更好的适应函数式编程,推荐使用函数式的风格解决break和contine的功能,而不是一个关键字

细节

  1. 在break() 函数 代码是
def break(): Nothing = { throw breakException }
  1. breakable(op: =>Unit) 函数, 是一个高阶函数,可以接受另外一个函数或者一段并执行,并处理如果捕获到breakException, 就 throw ex
def breakable(op: => Unit) {
  try {
    op
  } catch {
    case ex: BreakControl =>
      if (ex ne breakException) throw ex
  }
}
  1. scala中有这个风格,如果我们传入的是参数【代码】,是多行的,则我们的可以使用{} 替代()

  2. 在scala如果要使用continue的逻辑,则使用if-else 来处理

  3. 在for循环中,一样可以使用breakable( break() )

练习

  1. 100以内的数求和,求出当和第一次大于20的当前数

    // 如果不使用 Scala 的异常中断机制
    var sum = 0
    var flag = true
    for (i <- 1.to(100);if flag) {
        sum += i
        if (sum >= 20) {
            println(i)
            flag = false
        }
    }
    
    // 如果使用 Scala 的异常中断机制
    breakable {
        var sum = 0
        for (i <- 1 to 100) {
            sum += i
            if (sum >= 20) {
                println(i)
                break()
            }
        }
    }
    
  2. 实现登录验证,有三次机会,如果用户名为”cris” ,密码”123”提示登录成功,否则提示还有几次机会,请使用for 循环完成

    // 如果不使用 Scala 的异常中断机制
        var flg = true
    for (i <- 1 to 3; if flg) {
    
        println("请输入名字:")
        val name = StdIn.readLine()
        println("请输入密码:")
        val password = StdIn.readLine()
        if ("cris".equals(name) && "123".equals(password)) {
            println("登录成功!")
            flg = false
        } else {
            if (i != 3) {
                println("登录失败!你还剩下" + (3 - i) + "次机会!")
            } else {
                println("登录失败!你已经没有机会了!")
            }
        }
    }
    }
    
    // 如果使用 Scala 的异常中断机制
    breakable {
        for (i <- 1 to 3) {
            println("请输入名字:")
            val name = StdIn.readLine()
            println("请输入密码:")
            val password = StdIn.readLine()
            if ("cris".equals(name) && "123".equals(password)) {
                println("登录成功!")
                break()
            } else {
                if (i != 3) {
                    println("登录失败!你还剩下" + (3 - i) + "次机会!")
                } else {
                    println("登录失败!你已经没有机会了!")
                }
            }
        }
    }
    

    换句话说,Scala 通过异常中断机制来完成循环的终止,这个机制得以实现的前提就是函数式编程

  3. 根据规则统计路口通过总次数:金额大于50000,每次通过减少5%,;否则每次通过金额减去1000

    var money = 100000.0
    var count = 0
    while (money >= 1000) {
        count += 1
        if (money > 50000) {
            money *= 0.95
        } else {
            money -= 1000
        }
    }
    println("可以经过" + count + "次路口")
    
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值