为什么编译器会警告有关未初始化的变量,即使我已经分配了该变量的每个字段?

问题描述:

我完全分配在比赛的每一个可能的支柱名为xMyStruct实例字段:为什么编译器会警告有关未初始化的变量,即使我已经分配了该变量的每个字段?

enum MyEnum { 
    One, 
    Two, 
    Three, 
} 

struct MyStruct { 
    a: u32, 
    b: u32, 
} 


fn main() { 
    f(MyEnum::One); 
    f(MyEnum::Two); 
    f(MyEnum::Three); 
} 

fn f(y: MyEnum) -> MyStruct { 
    let mut x: MyStruct; 

    match y { 
     MyEnum::One => { 
      x.a = 1; 
      x.b = 1; 
     } 
     MyEnum::Two => { 
      x.a = 2; 
      x.b = 2; 
     } 
     MyEnum::Three => { 
      x.a = 3; 
      x.b = 3; 
     } 
    } 

    x 
} 

为什么编译器返回下面的错误?

error[E0381]: use of possibly uninitialized variable: `x` 
    --> src/main.rs:37:5 
    | 
37 |  x 
    | ^use of possibly uninitialized `x` 

我认为这是a known issue(另见它的相关问题)。

+3

'match'可以用在表达式上下文中;它可以作为最后一个用作返回值的表达式,或者作为'let x = match {...};'的右边 - 这完全避免了你的问题(但严格地说并不是你的问题的答案) 。 – Stefan

let x: MyStruct;没有将x设置为空值,它声明了一个变量。您仍然需要为其分配一个值。

fn f(y: MyEnum) -> MyStruct { 
    let x; 

    match y { 
     MyEnum::One => { 
      x = MyStruct { a: 1, b: 1 }; 
     } 
     MyEnum::Two => { 
      x = MyStruct { a: 2, b: 2 }; 
     } 
     MyEnum::Three => { 
      x = MyStruct { a: 3, b: 3 }; 
     } 
    } 

    x 
} 

换句话说,let x;创建未绑定变量,不具有与之相关联的值的变量。因此,您需要稍后将一些值绑定到它。

如果你只想从函数返回一个值,那么你可以利用几乎Rust中的每个语句都会产生一个值,而最后一个语句的值就是函数的返回值。

fn f(y: MyEnum) -> MyStruct { 
    use MyEnum::*; 

    let x = match y { 
     One => MyStruct { a: 1, b: 1 }, 
     Two => MyStruct { a: 2, b: 2 }, 
     Three => MyStruct { a: 3, b: 3 }, 
    }; 
    x 
} 

如果您愿意,也可以完全消除x

fn f(y: MyEnum) -> MyStruct { 
    use MyEnum::*; 

    match y { 
     One => MyStruct { a: 1, b: 1 }, 
     Two => MyStruct { a: 2, b: 2 }, 
     Three => MyStruct { a: 3, b: 3 }, 
    } 
} 
+0

您的评论与* alternative *是正确的,尽管该消息的原因目前是一个问题。看到我的编辑和我的文章结束:) –

+1

我怀疑这个问题不会很快解决。重要的编译器复杂性增加太少,回报不足。 – red75prime

+0

另外,我喜欢非未绑定的变量语义而不是未初始化的变量语义。第一个功能更强大。 – red75prime