2017-10-05 57 views
2

我完全分配在比賽的每一個可能的支柱名爲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

回答

9

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

相關問題