为什么编译器会警告有关未初始化的变量,即使我已经分配了该变量的每个字段?
我完全分配在比赛的每一个可能的支柱名为x
的MyStruct
实例字段:为什么编译器会警告有关未初始化的变量,即使我已经分配了该变量的每个字段?
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(另见它的相关问题)。
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 },
}
}
您的评论与* alternative *是正确的,尽管该消息的原因目前是一个问题。看到我的编辑和我的文章结束:) –
我怀疑这个问题不会很快解决。重要的编译器复杂性增加太少,回报不足。 – red75prime
另外,我喜欢非未绑定的变量语义而不是未初始化的变量语义。第一个功能更强大。 – red75prime
'match'可以用在表达式上下文中;它可以作为最后一个用作返回值的表达式,或者作为'let x = match {...};'的右边 - 这完全避免了你的问题(但严格地说并不是你的问题的答案) 。 – Stefan