Rust(4) - Ownership

Ownership 是 Rust 中控管記憶體資源的機制。有 GC 的語言如 Java 和 Python 會時不時檢查物件被引用的數量,若沒人引用時則銷毀該物件。C 語言的話要自己釋放記憶體資源。

Rust ownership 代表該物件只有一份,擁有 ownership 的人才能使用該物件。Ownership 帶來的一個好處是記憶體控管相當容易因為物件不會被複製多份,另外運行時的效能跟記憶體使用都能有顯著的提升。

1. Ownership:

Ownership 會出現在長度大小不定的物件上,即非基本型別的物件。

fn main() {
    let x: u32 = 10;
    print_u32(x);      // 這是一個 copy
    println!("{}", x); // ok

    let s: String = String::from("Hola mundo");
    print_string(s);   // print_string 借走 s 的所有權
    println!("{}", s); // oops!
}

fn print_u32(x: u32) {
    println!("{}", x);
}

fn print_string(s: String) {
    println!("{}", s);
}

為減少不必要的物件拷貝呼叫 print_string 時 Rust 把記憶體的使用權交給 print_string。

需要注意的是所有權會在範疇結束時被銷毀

fn main() {
    let s1: String = String::from("Hola mundo");
    {
        let s2 = s1;
        println!("s2: {}", s2);
    }
    println!("s1: {}", s1); // oops 所有權被 s2 拿走
}

透過表達式回傳拿回所有權。

fn main() {
    let s1: String = String::from("Hola mundo");
    let s1 = {
        let s2 = s1;
        println!("s2: {}", s2);
        s2
    };
    println!("s1: {}", s1); // ok
}

2. 有借有還:

我們可以透過 "&" 聲明說這個所有權借用是有借有還的,舉個例子。

fn main() {
    let s1: String = String::from("Hola mundo");
    {
        let s2 = &s1;
        println!("s2: {}", s2);
    } // 交還所有權
    println!("s1: {}", s1); // ok
}

同理 function 也可以如法炮製:

fn main() {
    let s: String = String::from("Hola mundo");
    print_string(&s);
    println!("{}", s);
}

// 宣吿 s 有借有還
fn print_string(s: &String) {
    println!("{}", s);
}

3. 有借有還又可變:

有時候你會希望被借用的資料是可變的,這時可以使用 "&mut"。

fn main() {
    let mut s: String = String::from("Hola ");
    let name:String = String::from("Newton");
    greet(&mut s, &name);
    println!("s: {}", s);
}

fn greet(s: &mut String, name: &String) {
    s.push_str(name) // 修改 s 的資料
}

留言

熱門文章