“显然”无法访问的块中的“借用可能未初始化的变量”错误

时间:2019-08-25 15:24:13

标签: rust

在下面的代码示例中,编译器可以确定if块不可访问,但仍然给我一个错误。

const A_MODE: bool = false; // I manually edit this to switch "modes"
fn main() {
    let a: Vec<u32>;
    if A_MODE {
        a = vec![1,2,3];
    }
    if A_MODE {
        println!("a: {:?}", a); // error: borrow of possibly uninitialized variable
    }
}

Rust Playground

我认为也许编译器确实在试图告诉我我需要在某个时候初始化a,但这可以很好地进行编译:

fn main() {
    let a: Vec<u32>;
    println!("Finished.");
}

错误仅仅是因为Rust编译器还不够智能,还是这种行为有某种目的?是否有任何简单的解决方法会导致类似的代码结构?

我知道我可以重组代码以使其正常工作,但是出于我的目的,上述结构是最直接,最直观的。我当前的解决方法是注释和取消注释代码块,这很不好玩。谢谢!

1 个答案:

答案 0 :(得分:3)

编译器不会在用于验证生存期和所有权的阶段扩展常量表达式,因此对于编译器而言不是“显而易见的”。

如果您真的不想运行该代码块,则可能要使用#[cfg](如果愿意,可以使用cfg-if板条箱)。

fn main() {
    let a: Vec<u32>;
    #[cfg(a-mode)] {
        a = vec![1,2,3];
    }
    #[cfg(a-mode)] {
        println!("a: {:?}", a); // error: borrow of possibly uninitialized variable
    }
}

这样,如果设置了a-mode cfg,它将编译两种用法而根本不会分支,否则将不会编译它们。

编译器意识到常量表达式条件永远不会改变,但是可以在编译的后期阶段进行处理,以实现诸如删除分支之类的优化。