rust 語法和語義 10 引用和借用
引用和借用 references and borrowing
所有權概念將依照官方介紹,分爲3個部分說明:
- 所有權 ownership
- 引用和借用 references and borrowing
- 生命週期 lifetimes
概述
操作格式 | 聲明 | example |
---|---|---|
&T | 引用(對象不可變) | &Vec |
&mut T | 引用(對象 可變) | &mut Vec |
* | 訪問 可變對象的引用 | {let y = &mut x; *y += 1;} |
- & 似乎類似 c 中的取地址操作,獲得一個指針
- * 似乎類似 c 中的取地址內容的操作,獲得指針所存地址裏的內容
<注意!> 借用規則
和 引用生命週期
。
引用 reference
&T // 引用(不可變) // e.g. &Vec<i32>
- 引用是
借用
了所有權,而不是擁有
所有權。 - 一個借用變量的綁定,在它離開作用域時並不釋放原始資源。
- 引用是
不可變的 immutable
,
可變引用:
&mutT // 引用( 可變) // e.g. &mut Vec<i32>
借用規則
- 任何
borrowing
必須比擁有者
更小的作用域
。 - 同一個 resource 的 borrowing,即
同一個作用域
下:
- 只有
N
個 不可變的引用 &T 或者 - 只有
1
個 可變的引用 &mut T
- 只有
當 2 個或更多個指針同時訪問同一內存位置,當它們中至少有 1 個在寫(那1個
可變的引用 &mut T
),同時操作在並不是同步的時候存在一個“數據競爭”。
所以解釋了爲什麼下面的代碼會出錯:
fn main() {
let mut x = 5;
let y = &mut x; // a mutable borrowing start here
*y += 1;
println!("{}", x); // a immutable borrowing try immut borrow
} // a mutable borrowing end here
可變借用 可以在創建一個 不可變引用 之前離開作用域:
fn main() {
let mut x = 5;
{
let y = &mut x; // a mutable borrowing start here
*y += 1;
} // a mutable borrowing end here
println!("{}", x); // a immutable borrowing
}
引用生命週期
引用必須與它引用的值存活得一樣長。不然會如 C 一樣引起 內存泄漏。
豆知識
- 釋放正在使用的指針,內存損壞
- 未釋放不使用的指針,內存泄漏