从 Option<&mut T> 读取参考多次 [英] Read reference from Option<&mut T> multiple times

查看:32
本文介绍了从 Option<&mut T> 读取参考多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Option<&mut T> 并且想要多次访问包含的引用,如下所示:

I have an Option<&mut T> and want to access the contained reference multiple times, like so:

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) = acode> 将导致编译器错误.如果没有第二个 if let ...,它可以完美运行,所以 a 不必是可变的.

That doesn't work, because if let Some(x) = a moves the reference value out of the Option, and the second if let Some(x) = a will result in a compiler error. Without the second if let ..., this works flawlessly, so a doesn't have to be mutable.

以下内容:

if let Some(ref x) = a {
    **x = 6;
}

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

gives an error: "assignment into an immutable reference".

这行得通:

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 是必要的,否则我会收到错误无法借用不可变匿名字段 (a:std::prelude::v1::Some).0作为可变".但这感觉不对:a 不应该是可变的,因为我没有修改它(见上文).

The mut a is necessary, otherwise I get an error "cannot borrow immutable anonymous field (a:std::prelude::v1::Some).0 as mutable". But this feels wrong: a shouldn't have to be mutable, because I'm not modifying it (see above).

正确的解决方案是什么?

What's the correct solution?

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

My problem is different from the one in How to pass `Option<&mut ...>` to multiple function calls without causing move errors?. I want to mutably dereference the reference in an Option<&mut T> multiple times, while the other one wants to pass an Option to multiple function invocations. The solutions to the other question are not applicable to my situation.

推荐答案

这个怎么样?

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 不需要是可变的.

In this case, a doesn't need to be mutable.

&mut ref mut 感觉有点别扭,但它是有道理的:首先我们通过解构移除一个 &mut,然后对再次值.当我们不使用Option时更明显:

The &mut ref mut feels a bit awkward, but it makes sense: first we remove a &mut by destructuring and then take a mutable reference to the value again. It's more obvious when we don't use the Option:

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

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

This also works. The third (special) line is equivalent to:

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.

In the Option case, we can't use the &mut *X version, but need to do all of it inside of the pattern. Thus the &mut ref mut x.

这篇关于从 Option&lt;&amp;mut T&gt; 读取参考多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆