我有一个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
不应该是可变的,因为我没有修改它(见上文).
什么是正确的解决方案?
我的问题不同于如何将`Option <&mut ...>`传递给多个函数调用而不会导致移动错误?.我希望在多次中可变地解引用引用Option<&mut T>
,而另一个想要传递Option
给多个函数调用.另一个问题的解决方案不适用于我的情况.
那这个呢?
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
。
归档时间: |
|
查看次数: |
167 次 |
最近记录: |