这是不是;“可能未初始化”;编译器错误是假警报吗?[rustc 1.51.0]

这是不是;“可能未初始化”;编译器错误是假警报吗?[rustc 1.51.0],rust,compiler-errors,compiler-bug,Rust,Compiler Errors,Compiler Bug,我遇到了可能未初始化的变量错误,尽管我确信这种情况永远不会发生。 (rustc--版本为rustc 1.51.0(2fd73fabe 2021-03-23)) fn示例(判别式:bool){ 让价值; if判别式{ 数值=0; } //更多代码[…] if判别式{ println!(“{}”,值); } } 以下是错误消息: error[E0381]: borrow of possibly-uninitialized variable: `value` --> src

我遇到了可能未初始化的变量错误,尽管我确信这种情况永远不会发生。
(rustc--版本为
rustc 1.51.0(2fd73fabe 2021-03-23)

fn示例(判别式:bool){
让价值;
if判别式{
数值=0;
}
//更多代码[…]
if判别式{
println!(“{}”,值);
}
}
以下是错误消息:

    error[E0381]: borrow of possibly-uninitialized variable: `value`
      --> src/raytracing/intersect.rs:8:24
       |
    10 |         println!("{}", value);
       |                        ^^^^^ use of possibly-uninitialized `value`
推理 我确实希望该示例能够编译(即使如图所示分离
if
-块不是“好风格”IMHO):

  • 由于
    discriminant
    是不可变的,我希望第二个
    if
    块在没有第一个块的情况下永远不会执行
  • 因此,变量应始终在
    println!中的借用时定义!()
可能的缓解措施 通过使用临时值初始化
,可以“静音”错误。
我强烈反对这种做法,因为

  • 临时值在数学意义上可能是错误的,因为它不可能在其他代码路径中计算
  • 此外,这可能会隐藏在开发过程中没有正确定义值的事实,从而限制编译器发出错误信号的能力
问题:

是否有人可以解释这种情况是有意的行为还是编译器错误?

你不是第一个看到这种行为的人,一般来说我不认为它是个bug。在你的情况下,这种情况非常简单和明显,你和我很容易对这种情况进行推理。但是,通常情况下,条件不需要很明显,例如,第二种情况可能有其他难以解释的条件,即使代码是正确的

此外,您希望编译器进行的分析(根据条件确定哪些代码是可访问的)通常只在编译器进行优化时进行。因此,即使编译器支持这种分析,它也可能无法在调试模式下工作。即使在最好的优化编译器和静态分析工具中,它也不能在所有情况下都工作

如果您对在这种情况下初始化虚拟值有哲学上的异议,可以使用
选项

fn example(discriminant: bool) {
    let value = if discriminant {
        Some(0)
    } else {
        None
    };

    // more code [...]

    if discriminant {
        println!("{}", value.unwrap());
    }
}

在本例中,您的值总是初始化的,在第二部分中,您声明它包含一个合适的非
None
值。如果您处于发布模式,编译器可能能够确定您的代码是正确的,并对其进行优化,以省略
选项(也可能不是)。

当然,代码很好。在这种情况下,编译器通常会警告未初始化的变量出现误报,这就是为什么它会说“可能”。没有办法让警告在所有情况下都100%正确,因为这是停止问题。
let value=discriminant。然后(| | 0)。。。如果let Some(v)=value{…}
当然,我会把它写成
如果let Some(v)
,但它的读写方式与我写的不同,我特意选择保持它与原始代码相似。虽然您可以使用
bool::then
,但它相对较新,即使它适用于OP,我还是更喜欢编写更兼容的代码,以帮助不使用最新版本的用户。谢谢,我知道编译器在一般情况下无法解决此问题!你的例子清楚地表明,我基本上可以使用一个选项,而不是一些sentinel值。我认为这个答案令人困惑,因为引入了优化器。流敏感类型检查(或者在本例中,活动性检查)已经存在,Rust已经部分支持它——您可以在循环中看到它的作用。优化器实际上与此无关。