Rust 從基礎到精通 — 第 5 講
建立具有泛型、特徵和生命週期的可重複使用 API
該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。
泛型僅針對不同類型重複使用相同的規則,而特徵定義類型必須提供的行為。 生命週期符號向編譯器描述引用之間的關係。
用特質定義行為
trait Damageable {
fn is_alive(&self) -> bool;
fn take_damage(&mut self, amount: i32);
}
fn attack(target: &mut impl Damageable, damage: i32) {
if target.is_alive() {
target.take_damage(damage);
}
}
攻擊可以使用實現 Damageable 的值,而無需知道特定類型。 與繼承層級結構相比,特徵更接近所需行為的契約。
泛型和特徵綁定
fn strongest<T>(values: &[T]) -> Option<&T>
where
T: Ord,
{
values.iter().max()
}
由於存在 T 實作 Ord 的條件,因此編譯器知道這些值可以進行比較。 無效的類型組合在執行前會被拒絕。
特質實現
struct Monster {
health: i32,
}
impl Damageable for Monster {
fn is_alive(&self) -> bool {
self.health > 0
}
fn take_damage(&mut self, amount: i32) {
self.health = (self.health - amount).max(0);
}
}
透過分離資料和公共契約,可以在外部類型允許的範圍內實現特徵。
生活關係
fn longer<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() >= b.len() { a } else { b }
}
'a 表示回傳引用不能比兩個輸入引用壽命更長的關係。 它不是延長引用的實際壽命或創建運行時資源的函數。
大多數簡單的生命週期都是由編譯器推斷的。 您應該先檢查 API 的所有權關係,看看傳回值借用了哪些輸入,而不是在發生錯誤時增加表示法。