Skip to content

建立 2026-09-19 更新 2026-09-19

生命週期

生命週期(lifetime)是編譯器用來確保「參照永遠有效」的機制。多數時候編譯器能自動推斷,你不會看到它;只有當編譯器無法判斷參照之間的關係時,才需要你用 'a 這樣的標註說明。本頁說明它解決什麼問題,以及何時需要手動標註。

生命週期解決什麼問題

每個參照都有一段「有效範圍」。如果參照比它指向的值活得更久,就會變成懸空參照。編譯器會比對兩者的範圍:

fn main() {
    // ❌ 無法編譯:x 的壽命比 r 短
    let r;
    {
        let x = 5;
        r = &x;
    } // x 在這裡被丟棄
    println!("{r}");
}

錯誤訊息是 x does not live long enoughr 想在大括號外使用,但 x 已經不在了。

函式中的生命週期標註

當函式回傳參照時,編譯器需要知道回傳的參照來自哪一個參數。下面的函式回傳兩個字串中較長的一個,但編譯器無法判斷回傳值是 x 還是 y

// ❌ 無法編譯:缺少生命週期標註
fn longest(x: &str, y: &str) -> &str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    println!("{}", longest("abc", "de"));
}

加上生命週期參數 'a 後,就是在告訴編譯器:「回傳值的有效期間,與兩個參數中較短的那一個相同。」

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let a = String::from("long string");
    let result;
    {
        let b = String::from("xyz");
        result = longest(a.as_str(), b.as_str());
        println!("{result}"); // 在 b 還活著的範圍內使用,沒問題
    }
}

標註不會改變壽命

生命週期標註只是描述參照之間的關係,讓編譯器能檢查,它不會延長或縮短任何值的壽命。

結構體中的參照

結構體若要存放參照,欄位也需要標註,表示結構體的實例不能比它所參照的資料活得更久:

struct Excerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().unwrap();
    let excerpt = Excerpt { part: first_sentence };
    println!("{}", excerpt.part);
}

自動推斷(省略規則)

大多數函式不用寫標註,是因為編譯器套用三條「生命週期省略規則」:

  1. 每個參照參數各自獲得一個生命週期。
  2. 只有一個輸入生命週期時,回傳值的參照就使用它。
  3. 若有 &self&mut self,回傳值的參照使用 self 的生命週期。

所以下面的函式不需要標註:

fn first_word(s: &str) -> &str {
    s.split_whitespace().next().unwrap_or("")
}

fn main() {
    println!("{}", first_word("hello world"));
}

'static

'static 表示這個參照在整個程式執行期間都有效。字串字面值都是 &'static str,因為它們直接存在執行檔中:

fn main() {
    let s: &'static str = "我永遠有效";
    println!("{s}");
}

不要為了消除錯誤就亂加 'static

遇到生命週期錯誤時,多半是設計上有問題。先想想:這個結構體真的需要存參照嗎?改成擁有資料(例如用 String 取代 &str)通常更簡單,只是多一次複製。

實用心法

  • 初學階段,遇到生命週期錯誤,優先考慮「回傳擁有的值」或「使用 String.clone()」。
  • 函式只回傳參照時,先確認它來自哪個參數,再標註。
  • 大多數程式碼根本不用寫生命週期,不必一開始就過度擔心。

推薦影音

生命週期入門

簡述:Let's Get Rusty 依照官方書籍第 10 章製作,專門講解生命週期標註的寫法與原因,適合第一次遇到 'a 的人。

進階:Crust of Rust 生命週期標註

簡述:Jon Gjengset 以直播方式逐步實作範例,探討生命週期的細節與常見陷阱,長度約兩小時,適合已有基礎、想深入理解的人。

所有權的三個核心觀念到此完成。接下來用它們來設計資料:資料建模