iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Rust

Rust 30 天養成計畫:從零到 CLI 專案系列 第 23

Day 23:生命週期(Lifetimes)

  • 分享至 

  • xImage
  •  

1. 為什麼需要生命週期(Lifetime)
在 Rust 中,所有的引用(reference)都有明確的存活範圍,編譯器必須確保引用的值在使用期間不會被釋放。
生命週期(Lifetime)就是 Rust 用來追蹤引用有效時間的一套標記系統,這能防止懸垂指標(dangling reference)等記憶體錯誤。

2. 基本例子:懸垂參考錯誤

fn main() {
    let r;
    {
        let x = 5;
        r = &x; //  x 在這裡離開作用域
    }
    println!("{}", r); // 編譯錯誤:r 指向已被釋放的值
}

輸出(編譯錯誤):

error[E0597]: `x` does not live long enough

Rust 編譯器會主動拒絕這種可能導致無效引用的程式。

3. 函數中的生命週期註記
如果一個函數回傳引用,Rust 需要知道輸入與輸出的生命週期之間的關係。

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

fn main() {
    let s1 = String::from("rust");
    let s2 = String::from("programming");
    let result = longest(&s1, &s2);
    println!("Longest: {}", result);
}

輸出:

Longest: programming

'a 是生命週期參數,用來告訴編譯器:回傳值的生命週期與參數中的最短者相同。

4. 結構體中的生命週期
若結構體中有引用欄位,也必須註明生命週期:

struct Book<'a> {
    title: &'a str,
}

fn main() {
    let name = String::from("Rust Book");
    let b = Book { title: &name };
    println!("Book title: {}", b.title);
}

輸出:

Book title: Rust Book

5. 靜態生命週期 'static
'static 代表資料在整個程式生命週期中都有效(例如字面字串常量)。

fn main() {
    let s: &'static str = "Hello, Rust!";
    println!("{}", s);
}

這是最長的生命週期,一般只在全域資料或常量中使用。

6. 學習心得與補充
今天學的生命週期讓我更理解為什麼 Rust 能在沒有垃圾回收的情況下仍保持記憶體安全。以前在 C++中,我常會不小心把指標指到已釋放的記憶體區塊,而 Rust 直接在編譯階段就阻止這種情況發生。雖然一開始看到 'a、'static 這些標註會有點抽象,但當我理解它其實只是保證引用活得夠久的規則時,一切就變得合理了。我覺得這個系統的設計很聰明,既能靜態檢查,又不影響執行效率。透過這次練習,我開始明白 Rust 的所有權、借用與生命週期三者是密不可分的核心。雖然這個主題需要時間消化,但也讓我看到 Rust 安全機制的底層邏輯。


上一篇
Day 22:自訂錯誤型別與 Result 應用進階
下一篇
Day 24:生命週期進階與自動推導(Lifetime Elision)
系列文
Rust 30 天養成計畫:從零到 CLI 專案30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言