所有權(Ownership)#

所有權 是 Rust 最核心、最獨特的特性。 透過所有權機制,Rust 在 不需要垃圾回收器(GC) 的情況下,保證記憶體安全。


1. 所有權的三條規則#

  1. Rust 中每一個值都有一個 擁有者(owner)
  2. 同一時間 只能有一個擁有者
  3. 當擁有者離開作用域(scope),值就會被 釋放(dropped)

2. 作用域(Scope)#

變數在宣告後開始有效,直到所在的區塊({})結束:

1
2
3
4
5
6
fn main() {
    {
        let s = String::from("hello"); // s 在此有效
        println!("{s}");
    } // 此處 s 離開作用域,記憶體被釋放
}

3. String 與堆積(Heap)#

Rust 的基本型別(如 i32bool)大小固定,存放在 堆疊(Stack) 上。 String 型別的內容大小可變,資料存放在 堆積(Heap) 上:

1
let s = String::from("hello");

s 離開作用域,Rust 會自動呼叫 drop 函數釋放堆積上的記憶體。


4. 移動(Move)#

String 指派給另一個變數時,不會複製資料,而是 移動(move) 所有權:

1
2
3
4
5
6
7
fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // s1 的所有權移動給 s2

    // println!("{s1}"); // 錯誤!s1 已失效
    println!("{s2}"); // 正確
}

這樣可以確保同一塊記憶體不會被釋放兩次。


5. 克隆(Clone)#

若需要深度複製堆積上的資料,可以使用 clone()

1
2
3
4
5
6
7
fn main() {
    let s1 = String::from("hello");
    let s2 = s1.clone(); // 深度複製

    println!("{s1}"); // 仍有效
    println!("{s2}");
}

clone() 會複製堆積上的資料,因此 成本較高


6. 複製(Copy)#

存放在堆疊上的型別(如整數、浮點數、布林、字元、只含 Copy 型別的元組)實作了 Copy trait,指派時 自動複製 ,不會移動:

1
2
3
4
5
6
7
fn main() {
    let x = 5;
    let y = x; // 複製,x 仍有效

    println!("{x}");
    println!("{y}");
}

7. 所有權與函數#

將值傳入函數時,所有權規則同樣適用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
fn main() {
    let s = String::from("hello");
    takes_ownership(s); // s 的所有權移入函數
    // s 在此已失效

    let n = 5;
    makes_copy(n); // n 是 Copy 型別,僅複製
    println!("{n}"); // 仍可使用
}

fn takes_ownership(some_string: String) {
    println!("{some_string}");
} // some_string 在此被釋放

fn makes_copy(some_integer: i32) {
    println!("{some_integer}");
}

8. 回傳值與所有權#

函數也可以透過回傳值來轉移所有權:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
fn main() {
    let s1 = gives_ownership();       // 取得函數回傳的所有權
    let s2 = String::from("hello");
    let s3 = takes_and_gives_back(s2); // s2 移入函數,再移回 s3
}

fn gives_ownership() -> String {
    String::from("yours")
}

fn takes_and_gives_back(s: String) -> String {
    s // 回傳,所有權移出
}

每次都要轉移所有權再傳回,非常繁瑣。下一章的 借用(Borrowing) 解決了這個問題。


Reference#

https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html