rust - 当返回对作用域外值的可变引用的不可变引用时,为什么在作用域结束时会丢弃可变引用?
问题描述
fn main() {
// block1: fails
{
let mut m = 10;
let n = {
let b = &&mut m;
&**b // just returning b fails
};
println!("{:?}", n);
}
// block2: passes
{
let mut m = 10;
let n = {
let b = &&m;
&**b // just returning b fails here too
};
println!("{:?}", n);
}
}
block1失败并出现以下错误:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:7:22
|
7 | let b = &&mut m;
| ^^^^^^ temporary value does not live long enough
8 | &**b // just returning b fails
9 | };
| - temporary value dropped here while still borrowed
...
12 | }
| - temporary value needs to live until here
我是否正确假设内部不可变引用超出了block2范围,而在block1中,即使有外部引用,内部可变引用也总是被删除?
解决方案
在这里将可变借用视为非Copy
结构(S
在下面的片段中)就足够了,它拥有引用值的所有权。该模型代表了可变借用的排他性。
基于此模型的推理:在 block2n
中是对 original 的引用m
,而在 block1中最终将是对可变借用所拥有n
的副本的引用。m
在这两个块中,内部引用在 let-block 的末尾被删除,但只有在 block1 中这会导致问题,因为在 block1 中,n
当这个内部引用被删除时,引用的目标仍然由内部引用拥有。
struct S { m: i32 }
let mut m = 10;
let n = {
let s = S { m };
let b = &s;
&(*b).m
}; // s is dropped
println!("{:?}", n);
在上面的代码片段s
中,拥有m
. 引用n
将指向n
删除时s
删除的副本 - 不允许。如果m
是非复制,m
则将移至s
,这将具有相同的含义。
在 block2 中,m
直接借用原件而不复制它。如果你强制复制,你会得到与 block1 相同的错误:
let mut m = 10;
let n = {
let m2 = m;
let mut a = &m2;
let b = &a;
&**b
};
println!("{:?}", n);
推荐阅读
- .htaccess - 如何使用 .htaccess 将 URL 重定向到另一个 URL
- android - 三星设备上的 ACTION_IMAGE_CAPTURE 模糊
- php - Laravel 更新或创建关系
- ios - 如何使用 ReactiveUI 和 DynamicData 链接 SourceList 观察?
- android - 运动布局阻止更新 recyclerview
- wordpress - 如果apache以nobody运行:nobody,如何以特定用户:nobody的身份上传文件?
- php - 对于routes.php,laravel 5.2中不存在的一些随机网址,无法重定向到404
- powerbi - 从今天开始获取特定日期()
- angular - 刷新 ng2-smart-table
- amazon-web-services - 在 AWS Quicksight 中的星期一开始一周