我有Option<&mut T>
并希望多次访问包含的引用,如下所示:
fn f(a: Option<&mut i32>) {
if let Some(x) = a {
*x = 6;
}
// ...
if let Some(x) = a {
*x = 7;
}
}
fn main() {
let mut x = 5;
f(Some(&mut x));
}
这不起作用,因为if let Some(x) = a
将参考值移出Option,第二个if let Some(x) = a
将导致编译器错误。没有第二个if let ...
,这可以完美地运作,因此a
不必是可变的。
以下内容:
if let Some(ref x) = a {
**x = 6;
}
给出错误:&#34;赋值给不可变引用&#34;。
这样可行:
fn f(mut a: Option<&mut i32>) {
if let Some(ref mut x) = a {
**x = 6;
}
if let Some(ref mut x) = a {
**x = 7;
}
}
mut a
是必要的,否则我会收到错误&#34;无法将不可变的匿名字段(a:std::prelude::v1::Some).0
借用为可变的&#34;。但这感觉不对:a
不应该是可变的,因为我没有修改它(见上文)。
什么是正确的解决方案?
我的问题与How to pass `Option<&mut ...>` to multiple function calls without causing move errors?中的问题不同。我希望在Option<&mut T>
中多次重新引用引用,而另一个想要将Option
传递给多个函数调用。其他问题的解决方案不适用于我的情况。
答案 0 :(得分:4)
这个怎么样?
fn f(a: Option<&mut i32>) {
if let Some(&mut ref mut x) = a {
*x = 6;
}
// ...
if let Some(&mut ref mut x) = a {
*x = 7;
}
}
在这种情况下,a
不需要是可变的。
&mut ref mut
感觉有点尴尬,但这是有道理的:首先我们通过解构删除&mut
,然后再次对该值进行可变引用。当我们不使用Option
:
let mr: &mut Vec<u32> = &mut vec![];
{
let &mut ref mut a = mr;
a.push(3);
}
mr.push(4);
这也有效。第三行(特殊)相当于:
let a = &mut *mr ;
// ^^^----- this is an lvalue of type `Vec<u32>`
// ^^^^^^^^^^^^----- together it's of type `&mut Vec<u32>` again
在Option
案例中,我们无法使用&mut *X
版本,但需要在模式中执行所有操作。因此&mut ref mut x
。