Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

控制流

根据条件是真还是假,或者根据某个值多次运行某些代码,决定是否运行某些代码,这是大多数编程语言的基本组成部分。在 X 语言中控制执行流程的最常见构造是 if 表达式和循环。

if 表达式

if 表达式允许你根据条件分支你的代码。你提供一个条件,然后陈述:“如果满足这个条件,运行这段代码块。如果条件不满足,不要运行这段代码块。”

让我们创建一个名为 branches.x 的新文件来探索 if 表达式:

let number = 3
if number < 5 {
  println("条件为真")
} else {
  println("条件为假")
}

所有 if 表达式都以 if 关键字开头,后跟一个条件。在这种情况下,条件检查 number 的值是否小于 5。我们将要执行的代码块放在条件之后的大括号中,条件为真时执行。

可选地,我们还可以包含一个 else 表达式,如果条件为假,我们选择执行该表达式,我们在这里选择了这样做。或者,你可以将 else 块看作是给程序一个默认的代码块来执行。

当你运行这个程序时,你会看到:

条件为真

让我们试着把 number 的值改为使条件为假的值,看看会发生什么:

let number = 7

再次运行程序,并查看输出:

条件为假

还值得注意的是,此代码中的条件必须是 boolean 类型。如果条件不是 boolean,我们会得到一个错误。让我们尝试运行这段代码:

let number = 3
if number {  // 错误:条件必须是 boolean 类型
  println("数字是三")
}

编译器会告诉你,X 语言期望条件是一个 boolean 类型,但得到了一个 integer。与 Ruby 和 JavaScript 等语言不同,X 语言不会自动尝试将非布尔类型转换为布尔类型。你必须显式并始终为 if 提供一个布尔值作为条件。

使用 else if 处理多个条件

你可以通过将 ifelse 组合在一个 else if 表达式中来使用多个条件。例如:

let number = 6
if number % 4 == 0 {
  println("数字能被 4 整除")
} else if number % 3 == 0 {
  println("数字能被 3 整除")
} else if number % 2 == 0 {
  println("数字能被 2 整除")
} else {
  println("数字不能被 4、3 或 2 整除")
}

这个程序有四个可能的路径。当你运行它时,你会看到:

数字能被 3 整除

当这个程序执行时,它会依次检查每个 if 表达式,并执行第一个条件为真的代码块。请注意,即使 6 也能被 2 整除,但我们没有看到 “数字能被 2 整除” 的输出,也没有看到来自 else 块的 “数字不能被 4、3 或 2 整除” 的文本。这是因为 X 语言只执行第一个条件为真的块,一旦找到一个块,它就不会检查其余的块。

使用太多的 else if 表达式会使你的代码变得混乱,所以如果我们有多个,我们可能想要重构我们的代码。我们将在后面关于模式匹配的章节中学习一个强大的 X 语言分支构造,叫做 match,正是针对这种情况。

在 let 语句中使用 if

因为 if 是一个表达式,我们可以在 let 语句的右侧使用它来将结果赋值给一个变量:

let condition = true
let number = if condition { 5 } else { 6 }
println("number 的值是: ", number)

number 变量将被绑定到一个值,该值取决于 if 表达式的结果。让我们运行这段代码:

number 的值是: 5

请记住,代码块计算结果为其最后一个表达式的值,而 if 本身就是一个表达式。在这种情况下,整个 if 表达式的值取决于执行哪个代码块。这意味着 if 的每个分支的可能结果必须是同一类型。让我们看看当类型不匹配时会发生什么:

let condition = true
let number = if condition { 5 } else { "six" }  // 错误!类型不匹配

整数和字符串是不同的类型,X 语言不允许这样做,因为在编译时它必须确定 number 变量的确切类型。如果 ifelse 臂具有不同的类型,这可能导致潜在的错误,编译器会在编译时捕获这些错误。

使用循环重复执行代码

多次执行一段代码通常很有用。对于这个任务,X 语言提供了几种循环,它们将遍历循环体中的代码,直到结束,然后立即回到开头再执行一次。

为了尝试循环,让我们创建一个名为 loops.x 的新文件。

while 条件循环

程序中经常需要评估循环内的条件。当条件为真时,循环运行。当条件不再为真时,循环退出。

下面的示例使用 while:程序循环三次,每次倒计时,然后在循环结束后打印一条消息并退出:

let mutable number = 3
while number != 0 {
  println(number, "!")
  number = number - 1
}
println("发射!")

只要条件为真,代码就会运行;否则,它会退出循环。

运行这个程序,你应该会看到:

3!
2!
1!
发射!

for 循环

for 循环用于遍历迭代器(如列表、范围等)中的每个元素:

for i in 0..5 {
  println(i)
}

这个程序会打印 0 到 4(不包含 5)。

你也可以使用包含范围 ..= 来包含右端点:

for i in 0..=5 {
  println(i)
}

这个程序会打印 0 到 5(包含 5)。

你可以遍历任何可迭代的集合,例如列表:

let names = ["Alice", "Bob", "Charlie"]
for name in names {
  println("Hello, ", name, "!")
}

break 和 continue

你可以使用 break 关键字提前退出循环,使用 continue 关键字跳过循环的当前迭代并继续下一次:

let mutable counter = 0
while counter < 10 {
  counter = counter + 1
  if counter == 5 {
    continue  // 跳过 5
  }
  if counter == 8 {
    break     // 在 8 时退出
  }
  println("counter = ", counter)
}

这个程序会打印:

counter = 1
counter = 2
counter = 3
counter = 4
counter = 6
counter = 7

总结

在本章中,我们介绍了通过 if 表达式和循环进行控制流的基础知识。有了这些,你应该能够编写一些基本的 X 语言程序了!

以下是我们学到的内容:

  • if 表达式根据条件进行分支
  • if 可以与 else ifelse 组合使用
  • if 可以在 let 中使用,因为它是一个表达式
  • while 只要条件为真就循环
  • for ... in 遍历迭代器
  • break 退出循环
  • continue 跳到循环的下一次迭代
  • main 函数不是必须的——你可以直接在文件顶层编写代码

到目前为止,你应该对 X 语言的工作方式有了很好的了解。接下来,让我们了解 X 语言的一个独特特性:所有权系统!