iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
Rust

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

Day 25:泛型、Trait Bound 與生命週期的綜合應用

  • 分享至 

  • xImage
  •  

1. 為什麼要結合這三者
在前面幾天,我分別學了泛型(讓程式能處理不同型別)、trait(限制泛型的行為),以及生命週期(確保引用安全),今天要學的就是這三者如何同時出現在同一個函數或結構中,

2. 範例:泛型 + Trait Bound + Lifetime 同時出現

use std::fmt::Display;

// 回傳兩個字串中較長者,並在印出訊息時要求 T 必須能 Display
fn longest_with_announcement<'a, T>(s1: &'a str, s2: &'a str, ann: T) -> &'a str
where
    T: Display,
{
    println!("Announcement: {}", ann);
    if s1.len() > s2.len() {
        s1
    } else {
        s2
    }
}

fn main() {
    let s1 = String::from("Rust");
    let s2 = String::from("Programming");
    let result = longest_with_announcement(&s1, &s2, "Comparing strings:");
    println!("Longest string is {}", result);
}

輸出:

Announcement: Comparing strings:
Longest string is Programming

這裡的函式同時用了:

  • 泛型 T:讓第三個參數可以是任意型別(只要能被印出)。
  • Trait Bound T: Display:保證 ann 可被 println! 使用。
  • Lifetime 'a:確保回傳值的引用不會比輸入短命。

3. 應用在結構體中

use std::fmt::Display;

struct Pair<'a, T>
where
    T: Display,
{
    first: &'a str,
    second: &'a str,
    note: T,
}

impl<'a, T> Pair<'a, T>
where
    T: Display,
{
    fn show(&self) {
        println!("({} , {}) - note: {}", self.first, self.second, self.note);
    }
}

fn main() {
    let p = Pair {
        first: "hello",
        second: "world",
        note: "Rust with lifetime and trait!",
    };
    p.show();
}

輸出:

(hello , world) - note: Rust with lifetime and trait!

這裡的 'a 負責確保 first 和 second 的引用安全,T: Display 則確保 note 可以輸出。

4. 為什麼這樣設計很重要

  • 寫一個回傳字串切片的函式時,必須考慮 'a。
  • 函式或結構需要支援多種型別時,用泛型。
  • 若要限制泛型的能力,就加 trait bound。

5. 學習心得與補充
今天的練習讓我把過去幾天學到的串起來,在學泛型或 trait 時,我覺得只是單獨的語法,但現在看到它們和 lifetime 結合後,整個型別系統的設計就變得立體起來。Rust 讓我能清楚地描述一個函數的輸入、輸出與約束條件,不需要依賴註解或猜測,編譯器就會幫我確認所有邏輯都安全。雖然語法看起來比較長,但其實每一個標註背後都有明確意義。


上一篇
Day 24:生命週期進階與自動推導(Lifetime Elision)
下一篇
Day 26:智慧指標(Smart Pointers)與 Box<T>
系列文
Rust 30 天養成計畫:從零到 CLI 專案30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言