多次阅读Option <&mut T>中的参考文献

Adr*_*her 8 rust

我有一个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));
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为if let Some(x) = a将参考值移出Option,第二个if let Some(x) = a将导致编译器错误.没有第二个if let ...,这完美无缺,所以a不必是可变的.

下列:

if let Some(ref x) = a {
    **x = 6;
}
Run Code Online (Sandbox Code Playgroud)

给出错误:"赋值给不可变引用".

这可行:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

mut a是必要的,否则我得到一个错误"不能借用不可变的匿名字段(a:std::prelude::v1::Some).0作为可变".但这感觉不对:a不应该是可变的,因为我没有修改它(见上文).

什么是正确的解决方案?

编辑1

我的问题不同于如何将`Option <&mut ...>`传递给多个函数调用而不会导致移动错误?.我希望在多次中可变地解引用引用Option<&mut T>,而另一个想要传递Option给多个函数调用.另一个问题的解决方案不适用于我的情况.

Luk*_*odt 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,a不需要是可变的。

&mut ref mut感觉有点尴尬,但它是有道理的:首先我们&mut通过解构删除 a,然后再次对该值进行可变引用。当我们不使用时,情况会更明显Option

let mr: &mut Vec<u32> = &mut vec![];
{
    let &mut ref mut a = mr;
    a.push(3);
}
mr.push(4);
Run Code Online (Sandbox Code Playgroud)

这也有效。第三行(特殊)相当于:

let a = &mut     *mr   ;
//               ^^^----- this is an lvalue of type `Vec<u32>`
//      ^^^^^^^^^^^^----- together it's of type `&mut Vec<u32>` again
Run Code Online (Sandbox Code Playgroud)

在这种Option情况下,我们不能使用&mut *X版本,但需要在模式内完成所有操作。就这样&mut ref mut x