Scala 控制流
最后修改于 2023 年 1 月 10 日
在本文中,我们将展示如何在 Scala 中控制程序流。
当 Scala 程序运行时,代码会从上到下执行。程序流可以通过各种关键字进行更改,包括 if/else、for、while 和 match。
控制流结构可用于有条件地或多次执行代码。
Scala if 条件
if/then 关键字用于创建简单的条件测试。它可以与 else if 和 else 关键字结合使用。
import scala.util.Random
@main def main() =
val r = Random.between(-10, 10)
if r > 0 then
println(s"positive value ($r)")
else if r == 0 then
println("zero value")
else
println(s"negative value ($r)")
我们随机选择一个值。根据结果值,我们打印一条消息。有三种可能的执行分支。
if r > 0 then
println(s"positive value ($r)")
如果 if 关键字后的表达式为 true,则执行下一条语句。其他分支不执行。
可以选择使用 end if 关键字来终止 if 条件。
@main def main() =
val r = Random.between(-10, 10)
if r > 0 then
println(s"positive value ($r)")
else if r == 0 then
println("zero value")
else
println(s"negative value ($r)")
end if
在程序中,我们使用 end if 结束 if 条件。
if/then 条件是表达式;它们可以返回值。
import scala.util.Random
@main def main() =
val r = Random.between(-10, 10)
val res = if r > 0 then
s"positive value ($r)"
else if r == 0 then
"zero value"
else
s"negative value ($r)"
println(res)
在此示例中,if/then 表达式返回一个结果,该结果稍后会被打印。
Scala while 循环
while/do 关键字用于创建循环。它一直运行直到满足给定条件。
@main def main() =
val vals = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val n = vals.length
var i = 0
var msum = 0
while i < n do
msum = msum + vals(i)
i = i + 1
println(msum)
我们有一个整数列表。我们使用 while 循环计算整数的总和。
val vals = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val n = vals.length
我们获取列表的长度。
var i = 0 var msum = 0
i 变量是计数器,msum 是计算总和的变量。
while i < n do
msum = msum + vals(i)
i = i + 1
while 循环运行直到计数器小于列表的长度。在块内,我们将当前值添加到 msum 并增加计数器。
$ scala main.scala 55
Scala for 循环
使用 for/do 关键字,我们迭代值的集合。
@main def main() =
val vals = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
var msum = 0
for e <- vals do
msum = msum + e
println(msum)
该示例计算列表中整数的总和。与使用 while 循环相比,我们获得了更简洁的代码。
for e <- vals do
msum = msum + e
在 for 循环中,我们逐个遍历列表的元素。
带 Map 的 Scala for 循环
For 循环也用于遍历 Map。
@main def main() =
val cts = Map("sk" -> "Slovakia", "ru" -> "Russia",
"de" -> "Germany", "no" -> "Norway")
for (k, v) <- cts do println(s"${k} ${v}")
我们有一个简单的 Map。我们遍历 Map 并打印其元素。
$ scala main.scala sk Slovakia ru Russia de Germany no Norway
带 Range 的 Scala for 循环
For 循环可以与值范围一起使用。
@main def main() =
for n <- 1 to 10 do
println(n)
使用 to 关键字创建整数范围。
for n <- 1 to 10 do
println(n)
我们使用 for 循环将数字 1 到 10 打印到控制台。
$ scala main.scala 1 2 3 4 5 6 7 8 9 10
多个生成器
For 循环可以有多个生成器。
@main def main() =
val vals1 = List('A', 'B', 'C', 'D', 'E')
val vals2 = List(1, 2, 3, 4, 5)
val res = for
e1 <- vals1
e2 <- vals2
yield
s"$e1$e2"
println(res)
使用两个 for 生成器,我们将两个列表的元素组合起来。
$ scala main.scala List(A1, A2, A3, A4, A5, B1, B2, B3, B4, B5, C1, C2, C3, C4, C5, ...
Scala for 表达式
For 表达式返回一个值。For 表达式使用 for/yield 关键字创建。For 表达式也称为 for 推导式。
For 表达式构建新的数据集合。
@main def main() =
val nums =
for i <- -5 to 5
yield i * 2
println(nums)
该示例使用 for 表达式创建了一个整数向量。
$ scala main.scala Vector(-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10)
在下面的示例中,我们使用 for 推导式创建了一个新列表。
case class User(name: String, age: Int)
val users = List(
User("John", 18),
User("Brian", 31),
User("Veronika", 23),
User("Lucia", 48),
User("Peter", 21))
val res =
for user <- users if user.age >= 20 && user.age < 30
yield user
@main def main() =
println(res)
res.foreach(println)
我们有一个用户列表。使用 for 表达式,我们创建一个新列表,其中只包含年龄在 20 到 30 岁之间的用户。
$ scala main.scala List(User(Veronika,23), User(Peter,21)) User(Veronika,23) User(Peter,21)
Scala for 守卫
守卫是 for 表达式中的 if 表达式,可以有条件地包含值。
@main def main() =
val words = List("sky", "war", "water", "rain",
"some", "cup", "train", "wrinkle", "worry")
val res = for
word <- words
if word.startsWith("w")
yield
word
println(res)
我们有一个字符串列表。我们使用 for 表达式遍历列表。但是,由于 if 守卫,最终输出中只包含以 'w' 开头的单词。
$ scala main.scala List(war, water, wrinkle, worry)
可以包含多个守卫。
@main def main() =
val words = List("sky", "war", "water", "rain",
"some", "cup", "train", "wrinkle", "worry")
val res = for
word <- words
if word.startsWith("w")
if word.endsWith("r")
yield
word
println(res)
使用两个守卫,我们只包含以“w”开头并以“r”结尾的单词。
$ scala main.scala List(war, water)
Scala match 表达式
模式匹配是一种强大的控制流结构,它允许我们将一个值与一系列模式进行比较,然后根据匹配的模式执行代码。
在 match 表达式中,每个被执行的选项称为一个 arm。
@main def main() =
val grades = List("A", "B", "C", "D", "E", "F", "FX")
for grade <- grades do
grade match
case "A" | "B" | "C" | "D" | "E" | "F" => println("passed")
case "FX" => println("failed")
我们有一个成绩列表。我们遍历列表并为每个值打印“通过”或“失败”。此示例使用多选项 arm,节省了大量空间。它比使用多个 if/else 关键字要短得多。
$ scala main.scala passed passed passed passed passed passed failed
在本文中,我们学习了 Scala 中的控制流结构。