靜態和動態排程

可以建立一個接受實現特定特徵的物件的函式。

靜態排程

fn generic_speak<T: Speak>(speaker: &T) {
    println!("{0}", speaker.speak());
}

fn main() {
    let person = Person {};
    let dog = Dog {};

    generic_speak(&person);
    generic_speak(&dog);
}

這裡使用靜態分派,這意味著 Rust 編譯器將為 DogPerson 型別生成 generic_speak 函式的專用版本。在編譯期間,這一代多型函式(或任何多型實體)的專用版本稱為單形化

動態排程

fn generic_speak(speaker: &Speak) {
    println!("{0}", speaker.speak());
}

fn main() {
    let person = Person {};
    let dog = Dog {};

    generic_speak(&person as &Speak);
    generic_speak(&dog); // gets automatically coerced to &Speak
}

這裡,編譯後的二進位制檔案中只存在單個版本的 generic_speak,而 speak() 呼叫是在執行時使用 vtable 查詢進行的。因此,使用動態分派可以加快編譯速度並縮小編譯後的二進位制檔案的大小,同時在執行時稍慢。

&SpeakBox<Speak> 型別的物件稱為特徵物件