Day 4:trait 作為參數與回傳
學習目標
- 用
impl Trait當參數 - 用泛型 + trait bound
- 回傳
impl Trait
今日重點
impl Trait 當參數
fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
&impl Summary:任何實作 Summary 的型別都能傳進來。
泛型 + bound 等價(但語法不同)
fn notify_generic<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
impl Trait與泛型不同點:泛型會保留實際型別(可做更多事,如擺進 Vec);impl Trait 是語法糖,呼叫端看不到型別名稱。
多重 bound
fn notify_both<T: Summary + std::fmt::Display>(item: &T) {
println!("{}: {}", item.summarize(), item);
}
回傳 impl Trait
fn returns_summarizable() -> impl Summary {
Tweet {
username: String::from("horse_ebooks"),
content: String::from("hello"),
}
}
回傳
impl Trait表示「回傳某個實現該 trait 的型別,但我不告訴你具體是哪個」。
練習
trait Area { fn area(&self) -> f64; }
struct Circle { r: f64 }
impl Area for Circle { fn area(&self) -> f64 { std::f64::consts::PI * self.r * self.r } }
// 1. 寫 fn print_area(shape: &impl Area)
fn print_area(shape: &impl Area) {
println!("Area = {}", shape.area());
}
// 2. 寫一個回傳 impl Area 的函式
fn make_circle(r: f64) -> impl Area { Circle { r } }
自我檢查
- 用 impl Trait 當參數
- 用泛型 + bound,並知其差別
- 回傳 impl Trait
- 會組合多重 bound
深入連結
- The Book 第 10 章「Traits as Parameters / Returning Types that Implement Traits」