Day 7:第五週總結練習

學習目標

  • 綜合運用泛型、trait、生命週期
  • 設計一個可重複使用的抽象

今日重點

本週回顧

  1. 泛型:<T>、泛型函式與結構、多重型別
  2. 單態化 = 零成本
  3. trait:定義、實作、預設方法
  4. trait 當參數 / 回傳 impl Trait
  5. 生命週期:'a、省略規則、'static

綜合練習:幾何圖形庫

// 1. 定義一個 trait,任何圖形都能算面積與週長
trait Shape {
    fn area(&self) -> f64;
    fn perimeter(&self) -> f64;
}

struct Circle { r: f64 }
struct Rect { w: f64, h: f64 }

impl Shape for Circle {
    fn area(&self) -> f64 { std::f64::consts::PI * self.r * self.r }
    fn perimeter(&self) -> f64 { 2.0 * std::f64::consts::PI * self.r }
}
impl Shape for Rect {
    fn area(&self) -> f64 { self.w * self.h }
    fn perimeter(&self) -> f64 { 2.0 * (self.w + self.h) }
}

// 2. 泛型函式:不靠 Box,直接用泛型 + bound
fn report<T: Shape>(shape: &T) {
    println!("area={:.2}, perimeter={:.2}", shape.area(), shape.perimeter());
}

// 3. 回傳 impl Shape
fn describe(shape: impl Shape) -> String {
    format!("area {:.2}", shape.area())
}

fn main() {
    let c = Circle { r: 2.0 };
    let r = Rect { w: 3.0, h: 4.0 };
    report(&c);
    report(&r);
    println!("{}", describe(c));
    println!("{}", describe(r));
}

挑戰

  • 加一個 compare_area(a: &impl Shape, b: &impl Shape) -> &'_ str 回傳面積較大者的名稱。
  • 想想「泛型 + trait」跟「繼承 + 多型」的差異,Rust 用哪個?

自我檢查

  • 能設計 trait + 泛型的抽象
  • 會用 impl Trait 當參數與回傳
  • 能寫泛型函式並用 bound 限制
  • 理解「組合 vs 繼承」的 Rust 風格

週總結

泛型 + trait 是 Rust 抽象的精華。你已具備設計模組化、可重用程式的能力。