Day 2:函式與所有權

學習目標

  • 理解傳值(move)與傳引用(borrow)的差別
  • 知道參數如何影響呼叫端變數的效力
  • 練習回傳所有權

今日重點

傳值 = 移動所有權

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

fn main() {
    let s = String::from("hello");
    print_string(s);        // s 的所有權「移進」函式
    // println!("{}", s);     // 錯誤!s 已無效
}

回傳所有權

fn give_back(s: String) -> String {
    s   // 所有權回傳給呼叫端
}

fn main() {
    let s = String::from("hello");
    let s = give_back(s);   // 所有權又回到這裡
    println!("{}", s);      // 有效!
}

傳引用(借用)避免移動

fn calculate_length(s: &String) -> usize {
    s.len()   // 借用,不取得所有權
}

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);   // &s1 借用
    println!("Length of '{}' is {}", s1, len);  // s1 仍有效!
}

練習

  1. 寫一個 capitalize 函式:一次接受 &String(借用),回傳 String(新的)。
  2. 觀察為什麼「借用」比「move」好用。

自我檢查

  • 知道傳值會轉移所有權
  • 知道傳 & 引用不會轉移所有權
  • 能寫出借用參數 + 回傳新值的函式

深入連結

  • The Book 第 4 章「Functions and Ownership」