循环和真实有什么区别?

aij*_*aij 25 loops rust

Rust教程,现在书中声称while true和之间存在差异loop,但在此阶段理解并不是非常重要.

如果你需要一个无限循环,你可能会想写这个:

while true {
Run Code Online (Sandbox Code Playgroud)

但是,Rust有一个专门的关键字loop来处理这种情况:

loop {
Run Code Online (Sandbox Code Playgroud)

Rust的控制流分析以不同的方式对待这个构造,因为我们知道它将始终循环.在这个阶段,这意味着什么并不是非常重要的细节,但总的来说,我们可以给编译器提供的信息越多,它对安全性和代码生成的影响就越大,所以你应该总是喜欢循环计划无限循环.

完成了一些编译器类型的工作后,我不得不想知道它有什么可能的语义差异,因为编译器弄清楚两者都是无限循环是微不足道的.

那么,编译器如何区别对待它们呢?

tel*_*ium 23

Reddit回答了这个问题.正如你所说,编译器可以是特殊情况while true,但事实并非如此.因为它没有,编译器不会在语义上推断,while true如果你突破循环,必须始终初始化循环中设置的未声明变量,而它是为loop循环执行的:

例如,它还有助于编译器推理循环

let x;
loop { x = 1; break; }
println!("{}", x)
Run Code Online (Sandbox Code Playgroud)

完全有效,而

let x;
while true { x = 1; break; }
println!("{}", x);
Run Code Online (Sandbox Code Playgroud)

无法编译"使用可能未初始化的变量"指向xprintln.在第二种情况下,编译器没有检测到循环体总是至少运行一次.

(当然,我们可以特殊情况下构造while true就像loop现在一样.我相信这就是Java所做的.)

  • 谢谢,尽管这引出了一个问题:为什么? (2认同)

use*_*458 13

一个主要区别是loop可以通过将值传递给来返回一个值breakwhile并且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)


Pet*_*all 5

首先要说的是,就性能而言,这些很可能是相同的。虽然 Rust 本身并没有对 做任何特别的事情while true,但 LLVM 可能确实进行了优化。Rust 编译器试图通过尽可能将优化委托给 LLVM 来使事情变得简单。

一般来说,我们可以提供给编译器的信息越多,它在安全性和代码生成方面的表现就越好

虽然某些常量表达式可能会被 LLVM 优化掉,但语言的语义不会因表达式是否为常量而改变。这很好,因为它也有助于人类更好地推理代码。

正因为true是一个简单的表达式,我们知道它是常数。所以是true != false[0; 1].len() == 1。但是呢num_cpus::get() == 1?我实际上不知道是否有一些编译目标可以保持不变,我也不应该考虑它!

当与生成的代码或宏结合使用时,telotortium 示例中的错误会更加严重。想象一个宏,它有时会产生一个简单的静态表达式,例如true == true,但有时会引用一个变量或调用一个函数。有时编译器能够确定循环运行一次,但有时它不能。现在在 Rust 中,该示例中的错误始终是错误,无论为该条件生成什么代码。没有惊喜。