我很难理解Rust是如何定义“作用域”的,或者可能是在No Starch Press的书中对“作用域”的定义(实际上我买了这本书)。
在第62页的顶部:
作用域是一个项目在程序中有效的范围。
下一段:
- 变量从它被声明的那一刻起直到当前作用域的末尾都是有效的。
在我看来,“范围”的定义是递归的。
现在翻到第72页的“参考资料和借阅”部分:
变量(参数)“s”的有效作用域与任何函数参数的作用域相同。
所以参数的作用域就是参数的作用域。这对我没有帮助。
第75页第2段:
.引用的作用域从它被引入的地方开始,一直持续到引用最后一次被使用。
啊哈。所以一个变量可以在它的“上下文”(函数)结束之前退出作用域。
Q1:函数中定义的变量和传递给该函数的参数的“作用域”定义是否不同?
Q2:引用的作用域处理与其他变量不同吗?
Q3:当一个函数参数或一个函数中声明的变量在函数结束之前超出作用域时,变量的存储是否在那时释放?即在函数返回给调用者之前?
1条答案
按热度按时间flmtquvp1#
实际上有三种不同的作用域:块的作用域、变量的作用域和引用的referent的作用域。
一个块(花括号,
{ ... }
)创建了一个作用域。这个作用域意味着在块内(直接)声明的变量将一直存在到它的结束。一个函数也以同样的方式创建一个作用域。一个变量的作用域基本上就是它的活性--它是活的。它通常是从它的声明开始,直到它被声明的块(或函数)的末尾。然而,一个变量可能被移动或删除,然后它的生命将在块之前或之后结束。它的作用域是在那里结束还是在块的末尾结束(value 的活性更长/更短)有待讨论。
所以当书上说:
作用域是程序中某项有效的范围。
这里的“scope”指的是变量的(项目的)作用域。
当它说:
该变量从它被声明的那一刻起直到当前作用域的末尾都是有效的。
这里的“scope”指的是 block 的作用域。
第三个作用域是引用的作用域,本书在第75页提到了它。通常,引用的作用域与它所引用的项的作用域相同,但由于Non-Lexical Lifetimes,它可能会在引用的最后一次使用之后提前结束。由于Rust的借用规则(共享xor可变),这会影响对同一项的其他引用何时可以使用。
关于您的问题:
函数中定义的变量与传递给该函数的参数的“作用域”定义是否不同?
两者都在函数的作用域中(如果变量没有在内部块中声明)。但是,函数中定义的变量在参数之前被删除,所以我们可以认为它们的作用域提前结束。
引用的作用域处理与其他变量不同吗?
不完全是,但是它们在最后一次使用后就被认为不再是活的,而不是在它们的块结束时。这不是引用所独有的,然而,这对于任何没有drop glue的变量都是正确的。
当一个函数参数或一个函数中声明的变量在函数结束之前超出作用域时,变量的存储是否在那时释放?即在函数返回给调用者之前?
这取决于你如何定义“内存释放”。
Rust唯一的保证是,在从函数返回后,堆栈指针将与进入它之前相同。通常,它只在函数返回时减少,一次完成而不是多次,并节省保存CPU时间。
Rust做出的另一个保证是
Drop
被确定性地调用。变量的Drop
在其块作用域的末尾被调用,除非它被从块作用域中移动。因此,变量 * 拥有的 * 资源(如堆分配)在那里被释放。是否释放变量的堆栈内存取决于你如何定义它。有时编译器可以重用变量的堆栈内存,如果它们的生存期不重叠。其他时候它不会,但在变量的作用域结束后它不会被使用。