我有以下代码:
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
的两个可变引用,但我找不到解决方案。
答案 0 :(得分:2)
如果您愿意为第一场比赛的副本做出折衷,您可以这样做:
#[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
但不是Clone
,则这也适用于Copy
。另一种选择是使用问题评论中建议的split_at_mut()
。
答案 1 :(得分:0)
如果您使用夜间编译器,则可以使用
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
}
}
此代码不具有超级可读性,因为所有内容都是参考,因为您需要详尽地介绍模式,但它符合您的要求。