附录 B:背景话题

本节涵盖了本指南中出现的常见编译器术语。我们会在某些特定于 Rust 的上下文中给出这些术语的一般定义。

什么是控制流图?

控制流图(control-flow graph)是编译器中常见的术语。如果你曾使用过流程图, 那么控制流图的概念对你来说会很熟悉。它是程序的一种表示方式, 能够以非常清晰的方式展现底层控制流。

控制流图由以边相连的一组基本块(basic block)构成。基本块的主要概念是 一组「一起」执行的语句,也就是说,只要你的分支跳到了基本块, 它就会从头到尾依次执行所有的语句。只有到基本块的最后才有可能分支到更多地方 (在 MIR 中,我们将最后一条语句称作终止句(terminator)):

bb0: {
    statement0;
    statement1;
    statement2;
    ...
    terminator;
}

你在 Rust 中使用的很多表达式都会编译成多个基本块。例如,考虑以下 if 语句:

a = 1;
if some_variable {
    b = 1;
} else {
    c = 1;
}
d = 1;

它会被编译成四个基本块

BB0: {
    a = 1;
    if some_variable { goto BB1 } else { goto BB2 }
}

BB1: {
    b = 1;
    goto BB3;
}

BB2: {
    c = 1;
    goto BB3;
}

BB3: {
    d = 1;
    ...;
}

在使用控制流图时,循环会简单地作为一个图中的环路出现,而 break 关键字则会被翻译成跳出此环路的一条路径。

什么是数据流分析?

静态程序分析(Static Program Analysis), 作者 Anders Møller 和 Michael I. Schwartzbach,它是一个绝佳的资源。

to be written

什么是「全称量化」?「存在量化」呢?

to be written

什么是协变和逆变?

详见 Rust 秘典 中的子定型(Subtyping)一章。

关于类型检查器如何处理型变的更多信息见本指南的 型变(variance)一章。

什么是「自由生存域」和「自由变量」?「约束生存域」呢?

我们来描述一下程序变量的自由和约束的概念,因为它们是我们最熟悉的概念。

  • 考虑此表达式,它创建了一个闭包:|a, b| a + b。在这里,a + b 中的 ab 指代该闭包被调用会时传入的参数。我们称 ab 在该闭包中是 被约束(bound)的,而闭包签名 |a, b| 是名字 ab约束位(binder) (因为对 ab 的任何引用都是指代它引入的变量)。

  • 考虑此表达式 a + b。在该表达式中,ab 均指代定义在该表达式之外 的局部变量。我们称这些变量在该表达式中自由出现(appear free) (即它们是**自由(free)的,而非被约束(bound)**的(被束缚的))。

所以现在你理解了:在某些「表达式、语句、还是别的什么」中的变量, 如果指代的是定义在该「表达式、语句、还是别的什么」之外的东西,那么它们就是 「自由出现」的。我们可以等价地称之为表达式中的「自由变量」, 毕竟它们就是一组「自由出现」的变量而已。

那么,它们与生存域(region)有什么关系呢?我们可以将类似的概念应用到类型和生存域上来。 例如,在类型 &'a u32 中,'a 是自由出现的。但在类型 for<'a> fn(&'a u32) 中则不是。