错误说值在循环迭代中移动到前一个,但这似乎不是真的
Error says value moved in previous in iteration of loop, but this doesn't seem true
如下面的代码所示,循环的每次迭代都定义了它自己的 Foo
实例,所以我看不出它是如何在“上一次循环迭代”中被“移动”的每个循环有一个新的 Foo
。
如何消除错误?
fn main() {
for i in 0..2 {
let vector: Foo;
// ------ move occurs because `vector` has type `Foo`, which does not implement the `Copy` trait
if i == 0 {
vector = Foo::Bar(vec![1_f32]);
} else if i == 1 {
vector = Foo::Baz(vec![1_u16]);
}
// - value moved here, in previous iteration of loop
println!("{}", vector.len());
// ^^^^^^ value used here after move
}
}
enum Foo {
Bar(Vec<f32>),
Baz(Vec<u16>)
}
impl Foo {
pub fn len(self) -> usize {
match self {
Foo::Bar(vector) => vector.len(),
Foo::Baz(vector) => vector.len(),
#[allow(unreachable_patterns)]
_ => unreachable!()
}
}
}
通过使用 match
语句,我设法消除了错误。我不知道为什么这行得通而以前的代码却行不通:
fn main() {
for i in 0..2 {
let vector: Foo = match i {
0 => Foo::Bar(vec![1_f32]),
1 => Foo::Baz(vec![1_u16]),
_ => unreachable!()
};
println!("{}", vector.len());
}
}
您的 if-else 链并不详尽:
fn main() {
for i in 0..2 {
let vector: Foo;
if i == 0 {
vector = Foo::Bar(vec![1_f32]);
} else if i == 1 {
vector = Foo::Baz(vec![1_u16]);
}
// What should happen if `i` is not 0 or 1 ?
// Then the app will try to use an uninitialized variable
// The compiler cannot figure out that it is impossible
// with the current input
println!("{}", vector.len());
}
}
因此当 i
不是 0
或 1
时,您必须添加一个 else
语句:
fn main() {
for i in 0..2 {
let vector: Foo;
if i == 0 {
vector = Foo::Bar(vec![1_f32]);
} else if i == 1 {
vector = Foo::Baz(vec![1_u16]);
} else {
unreachable!();
}
println!("{}", vector.len());
}
}
或者最好使用 match
语句(如您自己的回答),因为它更清晰易读:
fn main() {
for i in 0..2 {
let vector: Foo = match i {
0 => Foo::Bar(vec![1_f32]),
1 => Foo::Baz(vec![1_u16]),
_ => unreachable!()
};
println!("{}", vector.len());
}
}
相关问题(感谢@nneonneo):https://github.com/rust-lang/rust/issues/72649
如下面的代码所示,循环的每次迭代都定义了它自己的 Foo
实例,所以我看不出它是如何在“上一次循环迭代”中被“移动”的每个循环有一个新的 Foo
。
如何消除错误?
fn main() {
for i in 0..2 {
let vector: Foo;
// ------ move occurs because `vector` has type `Foo`, which does not implement the `Copy` trait
if i == 0 {
vector = Foo::Bar(vec![1_f32]);
} else if i == 1 {
vector = Foo::Baz(vec![1_u16]);
}
// - value moved here, in previous iteration of loop
println!("{}", vector.len());
// ^^^^^^ value used here after move
}
}
enum Foo {
Bar(Vec<f32>),
Baz(Vec<u16>)
}
impl Foo {
pub fn len(self) -> usize {
match self {
Foo::Bar(vector) => vector.len(),
Foo::Baz(vector) => vector.len(),
#[allow(unreachable_patterns)]
_ => unreachable!()
}
}
}
通过使用 match
语句,我设法消除了错误。我不知道为什么这行得通而以前的代码却行不通:
fn main() {
for i in 0..2 {
let vector: Foo = match i {
0 => Foo::Bar(vec![1_f32]),
1 => Foo::Baz(vec![1_u16]),
_ => unreachable!()
};
println!("{}", vector.len());
}
}
您的 if-else 链并不详尽:
fn main() {
for i in 0..2 {
let vector: Foo;
if i == 0 {
vector = Foo::Bar(vec![1_f32]);
} else if i == 1 {
vector = Foo::Baz(vec![1_u16]);
}
// What should happen if `i` is not 0 or 1 ?
// Then the app will try to use an uninitialized variable
// The compiler cannot figure out that it is impossible
// with the current input
println!("{}", vector.len());
}
}
因此当 i
不是 0
或 1
时,您必须添加一个 else
语句:
fn main() {
for i in 0..2 {
let vector: Foo;
if i == 0 {
vector = Foo::Bar(vec![1_f32]);
} else if i == 1 {
vector = Foo::Baz(vec![1_u16]);
} else {
unreachable!();
}
println!("{}", vector.len());
}
}
或者最好使用 match
语句(如您自己的回答),因为它更清晰易读:
fn main() {
for i in 0..2 {
let vector: Foo = match i {
0 => Foo::Bar(vec![1_f32]),
1 => Foo::Baz(vec![1_u16]),
_ => unreachable!()
};
println!("{}", vector.len());
}
}
相关问题(感谢@nneonneo):https://github.com/rust-lang/rust/issues/72649