问题
When pattern-matching, you can specify that you'd like to get a mutable reference to the contained value by using ref mut:
let mut score = Some(42);
if let Some(ref mut s) = score {
&mut s;
}
However, the inner value is not mutable:
error[E0596]: cannot borrow immutable local variable `s` as mutable
--> src/main.rs:4:14
|
4 | &mut s;
| ^
| |
| cannot reborrow mutably
| try removing `&mut` here
I tried to add in another mut, but that was not valid:
if let Some(mut ref mut s) = score {
&mut s;
}
error: the order of `mut` and `ref` is incorrect
--> src/main.rs:3:17
|
3 | if let Some(mut ref mut s) = score {
| ^^^^^^^ help: try switching the order: `ref mut`
error: expected identifier, found keyword `mut`
--> src/main.rs:3:25
|
3 | if let Some(mut ref mut s) = score {
| ^^^ expected identifier, found keyword
error: expected one of `)`, `,`, or `@`, found `s`
--> src/main.rs:3:29
|
3 | if let Some(mut ref mut s) = score {
| ^ expected one of `)`, `,`, or `@` here
回答1:
Not a direct answer, but possible workarounds
Create an intermediate variable
if let Some(ref mut s) = score {
let mut s = s;
&mut s;
}
#[derive(Debug)]
struct X;
enum Foo<T> {
Bar(T),
_Baz,
}
fn main() {
let mut score = Foo::Bar(X);
if let Foo::Bar(ref mut s) = score {
//let x = s;
//println!("{:?}", **x); ! not possible
let x = &mut &mut *s; // &mut &mut X
println!("{:?}", **x);
}
}
For Option specifically
if let Some(ref mut s) = score.as_mut() {
s; //:&mut &mut i32
}
if let Some(mut s) = score.as_mut() {
&mut s;
}
回答2:
Below code may give an idea for the possible solution to the problem. It's just a sample & testable code to provide a tiny example that aimed at the issue. Of course it may not cover the whole intents and purposes.
fn main() {
let mut score = Some(42i32);
let res = if let Some(41) = score {
println!("41 is matched");
1i32
} else if let Some(ref mut s) = score { //&mut score {
//let mut s2 = s;
//println!("s: {:#?}", s);
test(&mut &mut *s); // This part may be like this for borrowing
//println!("s: {:#?}", s);
1i32
} else {
0i32
};
//println!("Result: {:#?}", score);
assert_eq!(res, 1i32);
}
fn test(ref mut s: &mut &mut i32) -> i32 {
//let mut s2 = s;
return test2(&mut *s);
}
fn test2(n: &mut i32) -> i32 {
*n += 1;
//println!("Value: {}", *(*n));
return *n;
}
Live Version: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7c3e7e1ee712a31f74b201149365035f
Gist Link: https://gist.github.com/7c3e7e1ee712a31f74b201149365035f
来源:https://stackoverflow.com/questions/49710608/is-it-possible-to-create-a-mutable-value-of-a-mutable-reference-in-a-pattern