如何在嵌套匹配语句中多次访问可变向量?
How to access a mutable vector multiple times in nested match statements?
我有以下代码:
enum T {
A(bool),
B(u8),
}
fn main() {
let mut a = vec![T::A(true), T::B(42)];
match a[0] {
T::A(value) => println!("A: {}", value),
T::B(ref mut b) => {
match a[1] {
T::A(value) => println!("One more A: {}", value),
T::B(ref mut value) => *value += 1,
}
*b += 1
}
}
}
编译器抱怨:
error[E0499]: cannot borrow `a` as mutable more than once at a time
--> src/main.rs:11:19
|
8 | match a[0] {
| - first mutable borrow occurs here
...
11 | match a[1] {
| ^ second mutable borrow occurs here
...
17 | }
| - first borrow ends here
我知道问题是因为我有两个对 a
的可变引用,但我找不到解决方案。
如果您愿意为第一场比赛准备一份副本,您可以这样做:
#[derive(Debug, Copy, Clone)]
enum T {
A(bool),
B(u8),
}
fn main() {
let mut a = vec![T::A(true), T::B(42)];
let first = a[0]; // make a copy
match first {
// match on the copy
T::A(value) => println!("A: {}", value),
T::B(b) => {
match a[1] {
T::A(value) => println!("One more A: {}", value),
T::B(ref mut value) => *value += 1,
}
a[0] = T::B(b + 1) // then update the vector
}
}
println!("{:?}", a); // the original didn't get split
}
如果您的类型是 Clone
而不是 Copy
,这也适用于 Clone
。另一种选择是按照问题评论中的建议使用 split_at_mut()
。
如果你使用夜间编译器,你可以使用
- 特征
slice_patterns
匹配切片
split_at_mut
如评论中所建议
代码:
#![feature(slice_patterns)]
enum T {
A(bool),
B(u8),
}
fn main() {
let mut a = vec![T::A(true), T::B(42)];
match a.split_at_mut(0) {
(&mut [T::A(value)], _) => println!("A: {}", value),
(&mut [T::B(ref mut b)], ref mut rest) => {
match *rest {
&mut [T::A(value)] => println!("One more A: {}", value),
&mut [T::B(ref mut value)] => *value += 1,
_ => (), // mandatory, because we match against slice
}
*b += 1
}
_ => (), // mandatory, because we match against slice
}
}
这段代码可读性不是很好,因为一切都是参考,因为您需要详尽地涵盖模式,但它满足您的要求。
我有以下代码:
enum T {
A(bool),
B(u8),
}
fn main() {
let mut a = vec![T::A(true), T::B(42)];
match a[0] {
T::A(value) => println!("A: {}", value),
T::B(ref mut b) => {
match a[1] {
T::A(value) => println!("One more A: {}", value),
T::B(ref mut value) => *value += 1,
}
*b += 1
}
}
}
编译器抱怨:
error[E0499]: cannot borrow `a` as mutable more than once at a time
--> src/main.rs:11:19
|
8 | match a[0] {
| - first mutable borrow occurs here
...
11 | match a[1] {
| ^ second mutable borrow occurs here
...
17 | }
| - first borrow ends here
我知道问题是因为我有两个对 a
的可变引用,但我找不到解决方案。
如果您愿意为第一场比赛准备一份副本,您可以这样做:
#[derive(Debug, Copy, Clone)]
enum T {
A(bool),
B(u8),
}
fn main() {
let mut a = vec![T::A(true), T::B(42)];
let first = a[0]; // make a copy
match first {
// match on the copy
T::A(value) => println!("A: {}", value),
T::B(b) => {
match a[1] {
T::A(value) => println!("One more A: {}", value),
T::B(ref mut value) => *value += 1,
}
a[0] = T::B(b + 1) // then update the vector
}
}
println!("{:?}", a); // the original didn't get split
}
如果您的类型是 Clone
而不是 Copy
,这也适用于 Clone
。另一种选择是按照问题评论中的建议使用 split_at_mut()
。
如果你使用夜间编译器,你可以使用
- 特征
slice_patterns
匹配切片 split_at_mut
如评论中所建议
代码:
#![feature(slice_patterns)]
enum T {
A(bool),
B(u8),
}
fn main() {
let mut a = vec![T::A(true), T::B(42)];
match a.split_at_mut(0) {
(&mut [T::A(value)], _) => println!("A: {}", value),
(&mut [T::B(ref mut b)], ref mut rest) => {
match *rest {
&mut [T::A(value)] => println!("One more A: {}", value),
&mut [T::B(ref mut value)] => *value += 1,
_ => (), // mandatory, because we match against slice
}
*b += 1
}
_ => (), // mandatory, because we match against slice
}
}
这段代码可读性不是很好,因为一切都是参考,因为您需要详尽地涵盖模式,但它满足您的要求。