![](/img/trans.png)
[英]Why does the Rust compiler not optimize code assuming that two mutable references cannot alias?
[英]Why does the compiler error complain about multiple mutable references not dangling reference?
我試圖了解當函數重新借用可變引用時到底發生了什么。
fn main() {
let mut a = String::new();
let mut b = String::new();
let aa = &mut a;
let c = my_fun(aa, &mut b);
let d = &mut a;
println!("{}", c);
}
fn my_fun<'b>(x: &'b mut String, y: &'b mut String) -> &'b mut String { y }
根據我的理解, my_fun
將aa
重新借用為&*aa
,其 scope 將是my_fun
。 但是由於我在 function 簽名中創建的生命周期限制,reborrow 應該至少在&mut b
存在時存在。 所以println
強制重新借用直到它。
這不應該在 free 之后引發使用錯誤,因為匿名重新借用在 my_fun 中只有my_fun
嗎? 在這個 function 之外,這個引用應該是無效的。
但我得到的錯誤是:
error[E0499]: cannot borrow `a` as mutable more than once at a time
--> src/main.rs:7:13
|
5 | let aa= &mut a;
| ------ first mutable borrow occurs here
6 | let c = my_fun(aa, &mut b);
7 | let d = &mut a;
| ^^^^^^ second mutable borrow occurs here
8 | println!("{}", c);
| - first borrow later used
如果可變引用只是被復制而不是在 function 中重新借用,這將是有意義的。
根據我的理解,
my_fun
將aa
重新借用為&*aa
,其 scope 將是my_fun
。
不完全是這樣。
讓我們回顧一下:為什么要重新借用?
&T
和&mut T
之間存在根本區別: &T
是Copy
,而&mut T
甚至不是Clone
。 結果是&mut T
只能移動,因此調用如下:
let x: &mut T = /*...*/;
func(x);
會導致x
在調用后無法使用。 解決方法是引入一個臨時的:
let x: &mut T = /*...*/;
let tmp = &mut *x;
func(tmp);
這個臨時對象將重新借用x
的指針對象,並由func
消耗。
還有……那是再借! 編譯器內置了這種“臨時”創建,純粹是為了符合人體工程學!
考慮到這一點,讓我們 go 回到:
根據我的理解,
my_fun
將aa
重新借用為&*aa
,其 scope 將是my_fun
。
生命周期通常更像是一個范圍而不是一個點,這里也是如此。
在我上面的示例中, tmp
的生命周期受到兩種方式的限制:
x
的值。func
的值。這是另一種說法,它可以是這些界限之間的任何東西。
我相信你在這里過度思考“重新借用”。
您應用的生命周期要求表示返回值引用的事物至少具有參數引用的事物的生命周期。 這是真的(如果不能證明是真的,這將無法編譯)。 所以不可能有懸空引用。
沒有單獨的“重新借用”參考。 借用是編譯器內部的簿記,以跟蹤生命周期。 沒有實際發生或什至特別暗示的let x = &*aa
步驟。 這不像引用計數,其中 memory 實際上在運行時發生變化。
在my_fun
內部, y
是一個范圍為 function 的引用。但返回值的范圍為調用者。 (如果這不是真的,函數將無法使用,與&mut
無關。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.