使用捕获模式匹配改变 Vec 元素
Mutate a Vec element with a capturing pattern match
我可以更改 vec 的最后一个元素:
#[derive(Debug)]
enum Type {
A,
B,
C,
}
fn main() {
let mut v = vec![Type::A, Type::B, Type::B];
match v.last_mut(){
None => v.push(Type::A),
Some(last) => *last = Type::C,
}
println!("{:?}", v)
}
==> 打印 [A, B, C]
.
但是如果我的枚举常量有数据,我似乎无法捕获它们...
例如:
#[derive(Debug)]
enum Type {
A(i32),
B(i32),
C(i32),
}
fn main() {
let mut v = vec![Type::A(0), Type::B(1), Type::B(2)];
match v.last_mut(){
None => v.push(Type::A(0)),
Some(last @ Type::B(_)) => *last = Type::C(42),
Some(Type::A(_)) | Some(Type::C(_)) => {}
}
println!("{:?}", v);
}
==> 打印 [A(0), B(1), C(42)]
上面的工作只是因为我在 Type::B(_)
里面放了一个 _
。
如果我尝试使用此行捕获它以在 Type::C()
中使用:
Some(last @ Type::B(p)) => *last = Type::C(*p),
我收到三个奇怪的错误:
error: borrow of moved value
--> src/main.rs:13:14
|
13 | Some(last @ Type::B(p)) => *last = Type::C(*p),
| ----^^^^^^^^^^^-^
| | |
| | value borrowed here after move
| value moved into `last` here
| move occurs because `last` has type `&mut Type` which does not implement the `Copy` trait
error[E0658]: pattern bindings after an `@` are unstable
--> src/main.rs:13:29
|
13 | Some(last @ Type::B(p)) => *last = Type::C(*p),
| ^
|
= note: see issue #65490 <https://github.com/rust-lang/rust/issues/65490> for more information
error[E0382]: borrow of moved value
--> src/main.rs:13:29
|
13 | Some(last @ Type::B(p)) => *last = Type::C(*p),
| ---------------^-
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `&mut Type`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving the value
|
13 | Some(ref last @ Type::B(p)) => *last = Type::C(*p),
| ^^^
error: aborting due to 3 previous errors
我怎样才能完成这项工作,即捕获 B (a &mut i32
) 的当前值,并将其传递给 C?
以可变方式捕获 last
并以不变方式捕获其中的值意味着您同时拥有对同一数据的 mut
引用和共享引用。 Rust 的所有权模型禁止这种别名,因此借用检查器拒绝它。
How could I make this work, i.e. capture the current value of B (a &mut i32
), and pass it to C?
您可以捕获最后一个值并在单独的内部匹配中检查它。这避免了对别名引用的初始请求,这对 Rust 来说是一个问题。相反,它从外部 last
引用创建内部 p
引用,只要在内部引用的生命周期内不使用外部引用,就允许这样做。换句话说,这编译:
match v.last_mut() {
None => v.push(Type::A(0)),
Some(last) => {
match last {
Type::B(p) => *last = Type::C(*p),
Type::A(_) | Type::C(_) => (),
}
}
}
我可以更改 vec 的最后一个元素:
#[derive(Debug)]
enum Type {
A,
B,
C,
}
fn main() {
let mut v = vec![Type::A, Type::B, Type::B];
match v.last_mut(){
None => v.push(Type::A),
Some(last) => *last = Type::C,
}
println!("{:?}", v)
}
==> 打印 [A, B, C]
.
但是如果我的枚举常量有数据,我似乎无法捕获它们... 例如:
#[derive(Debug)]
enum Type {
A(i32),
B(i32),
C(i32),
}
fn main() {
let mut v = vec![Type::A(0), Type::B(1), Type::B(2)];
match v.last_mut(){
None => v.push(Type::A(0)),
Some(last @ Type::B(_)) => *last = Type::C(42),
Some(Type::A(_)) | Some(Type::C(_)) => {}
}
println!("{:?}", v);
}
==> 打印 [A(0), B(1), C(42)]
上面的工作只是因为我在 Type::B(_)
里面放了一个 _
。
如果我尝试使用此行捕获它以在 Type::C()
中使用:
Some(last @ Type::B(p)) => *last = Type::C(*p),
我收到三个奇怪的错误:
error: borrow of moved value
--> src/main.rs:13:14
|
13 | Some(last @ Type::B(p)) => *last = Type::C(*p),
| ----^^^^^^^^^^^-^
| | |
| | value borrowed here after move
| value moved into `last` here
| move occurs because `last` has type `&mut Type` which does not implement the `Copy` trait
error[E0658]: pattern bindings after an `@` are unstable
--> src/main.rs:13:29
|
13 | Some(last @ Type::B(p)) => *last = Type::C(*p),
| ^
|
= note: see issue #65490 <https://github.com/rust-lang/rust/issues/65490> for more information
error[E0382]: borrow of moved value
--> src/main.rs:13:29
|
13 | Some(last @ Type::B(p)) => *last = Type::C(*p),
| ---------------^-
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `&mut Type`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving the value
|
13 | Some(ref last @ Type::B(p)) => *last = Type::C(*p),
| ^^^
error: aborting due to 3 previous errors
我怎样才能完成这项工作,即捕获 B (a &mut i32
) 的当前值,并将其传递给 C?
以可变方式捕获 last
并以不变方式捕获其中的值意味着您同时拥有对同一数据的 mut
引用和共享引用。 Rust 的所有权模型禁止这种别名,因此借用检查器拒绝它。
How could I make this work, i.e. capture the current value of B (a
&mut i32
), and pass it to C?
您可以捕获最后一个值并在单独的内部匹配中检查它。这避免了对别名引用的初始请求,这对 Rust 来说是一个问题。相反,它从外部 last
引用创建内部 p
引用,只要在内部引用的生命周期内不使用外部引用,就允许这样做。换句话说,这编译:
match v.last_mut() {
None => v.push(Type::A(0)),
Some(last) => {
match last {
Type::B(p) => *last = Type::C(*p),
Type::A(_) | Type::C(_) => (),
}
}
}