0%

scala流程控制

Scala 流程控制:顺序、分支与循环的优雅实现

流程控制是编程语言的基础,用于控制代码的执行顺序。Scala 作为一门多范式语言,在流程控制上既保留了与 Java 相似的语法,又融入了函数式编程的特性,尤其在循环和中断处理上有独特设计。本文详细介绍 Scala 的三大流程控制语句。

顺序控制

顺序控制是最基础的流程模式,代码按照从上到下的顺序依次执行,没有跳转或分支。这是所有编程语言的默认执行方式,Scala 也不例外。

1
2
3
4
5
// 顺序执行示例
val a = 10
val b = 20
val sum = a + b
println(s"a + b = $sum") // 先计算sum,再打印结果

特点

  • 无特殊关键字,代码自然流淌。
  • 适用于简单的步骤化操作(如变量定义、计算、输出)。

分支控制(if…else)

Scala 的分支控制通过 if...else if...else 实现,与 Java 语法相似,但更灵活 ——if 表达式有返回值,可直接赋值给变量。

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
val age = 19

// 多分支判断
if (age > 22) {
println("这么大岁数了,什么时候结婚生孩子呀")
} else if (age > 18) {
println("有对象了吗")
} else if (age > 16) {
println("好好学习,可不能早恋耽误学习")
} else {
println("你还小")
}

作为表达式的 if

Scala 中 if 是表达式(有返回值),而非单纯的语句。这意味着可以将 if...else 的结果直接赋值给变量。

1
2
3
4
5
6
7
8
9
10
val score = 85
val result = if (score >= 60) "及格" else "不及格"
println(result) // 输出:及格

// 复杂分支的返回值
val grade = if (score >= 90) "A"
else if (score >= 80) "B"
else if (score >= 60) "C"
else "D"
println(grade) // 输出:B

无返回值的分支

若分支不需要返回有意义的值,可返回 Unit 类型(类似 Java 的 void),用 () 表示。

1
2
3
val x = 3
val res = if (x > 5) 10 else () // else分支返回Unit
println(res) // 输出:()

优势

  • 避免临时变量,直接通过 if 表达式赋值,代码更简洁。
  • 支持函数式编程风格,可作为高阶函数的参数。

循环控制

Scala 提供 forwhiledo...while 三种循环,其中 for 循环功能最强大,支持多种遍历方式;whiledo...while 则与 Java 用法类似,但 Scala 更推荐使用 for

for 循环:灵活的遍历工具

Scala 的 for 循环(也称 “for 推导式”)支持范围遍历、集合遍历、守卫条件、变量引入等,语法灵活。

(1)范围遍历
  • to 关键字:左闭右闭区间(包含起止值)。
  • until 关键字:左闭右开区间(包含起始值,不包含结束值)。
1
2
3
4
5
6
7
8
9
10
11
// 1 to 3:遍历1、2、3(左闭右闭)
for (i <- 1 to 3) {
print(i + "\t") // 输出:1 2 3
}

println()

// 1 until 3:遍历1、2(左闭右开)
for (i <- 1 until 3) {
print(i + "\t") // 输出:1 2
}
(2)集合遍历

直接遍历数组、列表等集合元素:

1
2
3
4
val fruits = Array("apple", "banana", "orange")
for (fruit <- fruits) {
println(fruit) // 依次输出数组中的元素
}
(3)循环守卫(条件过滤)

通过 if 条件过滤循环元素,类似 continue 的效果(只执行满足条件的迭代)。

1
2
3
4
5
6
7
8
9
10
11
// 遍历1-5,只打印偶数
for (i <- 1 to 5 if i % 2 == 0) {
print(i + "\t") // 输出:2 4
}

// 等价于带if判断的普通循环
for (i <- 1 to 5) {
if (i % 2 == 0) {
print(i + "\t")
}
}
(4)引入临时变量

在循环中定义临时变量,简化操作(多个表达式用分号分隔)。

1
2
3
4
5
6
7
8
// 遍历1-3,同时计算i的平方
for (i <- 1 to 3; square = i * i) {
println(s"$i 的平方是 $square")
}
// 输出:
// 1 的平方是 1
// 2 的平方是 4
// 3 的平方是 9
(5)嵌套循环

通过多个生成器实现嵌套循环,无需多层缩进。

1
2
3
4
5
6
7
8
9
// 嵌套循环:遍历1-2和3-4的组合
for (i <- 1 to 2; j <- 3 to 4) {
println(s"i=$i, j=$j")
}
// 输出:
// i=1, j=3
// i=1, j=4
// i=2, j=3
// i=2, j=4

while 循环

while 循环先判断条件,满足则执行循环体,语法与 Java 一致。

1
2
3
4
5
6
7
8
9
10
11
var i = 0
while (i < 5) {
println(s"line $i")
i += 1 // 注意:Scala中没有i++,需用i += 1
}
// 输出:
// line 0
// line 1
// line 2
// line 3
// line 4

注意

  • Scala 不推荐频繁使用 while,因为它依赖可变变量(如 i),不符合函数式编程的 “无副作用” 原则。
  • 优先用 for 循环替代,尤其是遍历集合时。

do…while 循环

do...while 先执行循环体,再判断条件,确保循环体至少执行一次。

1
2
3
4
5
6
7
8
9
var count = 3
do {
println(s"count = $count")
count -= 1
} while (count > 0)
// 输出:
// count = 3
// count = 2
// count = 1

循环中断:打破常规的函数式实现

Scala 没有 breakcontinue 关键字,而是通过 Breaks 工具类的 break()breakable() 实现循环中断,本质是通过异常机制控制流程。

使用步骤:
  1. 导入 scala.util.control.Breaks
  2. breakable() 包裹循环体(用于捕获中断异常)。
  3. break() 触发中断(抛出特殊异常)。
1
2
3
4
5
6
7
8
9
10
11
12
import scala.util.control.Breaks._

// 遍历1-10,遇到5则中断循环
breakable {
for (i <- 1 to 10) {
if (i == 5) {
break() // 触发中断
}
print(i + "\t")
}
}
// 输出:1 2 3 4

原理

  • break() 抛出 BreakControl 异常。
  • breakable() 捕获该异常并忽略,避免程序终止。
模拟 continue 效果

结合循环守卫,可实现类似 continue 的功能(跳过当前迭代):

1
2
3
4
5
6
7
8
9
10
// 遍历1-10,跳过偶数
for (i <- 1 to 10) {
breakable {
if (i % 2 == 0) {
break() // 跳过当前迭代
}
print(i + "\t")
}
}
// 输出:1 3 5 7 9

流程控制的最佳实践

  1. 优先用 for 循环for 推导式功能强大,支持多种遍历场景,且更符合 Scala 风格。
  2. 利用 if 表达式的返回值:减少临时变量,例如 val result = if (cond) a else b
  3. 慎用 while 循环:尽量用 for 或递归替代,避免可变变量。
  4. 合理使用循环中断breakable + break 是 Scala 推荐的中断方式,清晰且安全。

欢迎关注我的其它发布渠道