Rust教程,现在书中声称while true
和之间存在差异loop
,但在此阶段理解并不是非常重要.
如果你需要一个无限循环,你可能会想写这个:
Run Code Online (Sandbox Code Playgroud)while true {
但是,Rust有一个专门的关键字loop来处理这种情况:
Run Code Online (Sandbox Code Playgroud)loop {
Rust的控制流分析以不同的方式对待这个构造,因为我们知道它将始终循环.在这个阶段,这意味着什么并不是非常重要的细节,但总的来说,我们可以给编译器提供的信息越多,它对安全性和代码生成的影响就越大,所以你应该总是喜欢循环计划无限循环.
完成了一些编译器类型的工作后,我不得不想知道它有什么可能的语义差异,因为编译器弄清楚两者都是无限循环是微不足道的.
那么,编译器如何区别对待它们呢?
tel*_*ium 23
Reddit回答了这个问题.正如你所说,编译器可以是特殊情况while true
,但事实并非如此.因为它没有,编译器不会在语义上推断,while true
如果你突破循环,必须始终初始化循环中设置的未声明变量,而它是为loop
循环执行的:
例如,它还有助于编译器推理循环
Run Code Online (Sandbox Code Playgroud)let x; loop { x = 1; break; } println!("{}", x)
完全有效,而
Run Code Online (Sandbox Code Playgroud)let x; while true { x = 1; break; } println!("{}", x);
无法编译"使用可能未初始化的变量"指向
x
中println
.在第二种情况下,编译器没有检测到循环体总是至少运行一次.(当然,我们可以特殊情况下构造
while true
就像loop
现在一样.我相信这就是Java所做的.)
use*_*458 13
一个主要区别是loop
可以通过将值传递给来返回一个值break
。while
并且for
不会:
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
assert_eq!(result, 20);
}
Run Code Online (Sandbox Code Playgroud)
首先要说的是,就性能而言,这些很可能是相同的。虽然 Rust 本身并没有对 做任何特别的事情while true
,但 LLVM 可能确实进行了优化。Rust 编译器试图通过尽可能将优化委托给 LLVM 来使事情变得简单。
一般来说,我们可以提供给编译器的信息越多,它在安全性和代码生成方面的表现就越好
虽然某些常量表达式可能会被 LLVM 优化掉,但语言的语义不会因表达式是否为常量而改变。这很好,因为它也有助于人类更好地推理代码。
正因为true
是一个简单的表达式,我们知道它是常数。所以是true != false
和[0; 1].len() == 1
。但是呢num_cpus::get() == 1
?我实际上不知道是否有一些编译目标可以保持不变,我也不应该考虑它!
当与生成的代码或宏结合使用时,telotortium 示例中的错误会更加严重。想象一个宏,它有时会产生一个简单的静态表达式,例如true == true
,但有时会引用一个变量或调用一个函数。有时编译器能够确定循环运行一次,但有时它不能。现在在 Rust 中,该示例中的错误始终是错误,无论为该条件生成什么代码。没有惊喜。