Rust-dyn 關鍵字


dyn是trait對象類型的前綴

dyn關鍵字用於強調相關trait的方法是動態分配的。要以這種方式使用trait,它必須是“對象安全”的。

與泛型參數或植入型特質不同,編譯器不知道被傳遞的具體類型。也就是說,該類型已經被抹去。因此,一個dyn Trait引用包含兩個指針。一個指針指向數據(例如,一個結構的實例)。另一個指針指向方法調用名稱與函數指針的映射(被稱為虛擬方法表各vtable)。

impl traitdyn trait 在Rust分別被稱為靜態分發和動態分發,即當代碼涉及多態時,需要某種機制決定實際調動類型。

使用dyn返回trait

Rust編譯器需要知道每個函數的返回類型需要多少空間。這意味着所有函數都必須返回一個具體類型。我們通過以下示例1來展示:

文件名: src/lib.rs

pub trait Animal {
    fn noise(&self);
}

pub struct Sheep {}

pub struct Cow {}

impl Animal for Sheep {
    fn noise(&self){
        println!("mamamama!");
    }
}

impl Animal for Cow {
    fn noise(&self) {
        println!("moooooo!");
    }
}

示例1有trait Animal,我們不能編寫返回Animal的函數,因為其不同的實將需要不同的內存量。

但是,有一個簡單的解決方法。相比直接返回一個trait對象,我們的函數返回一個包含一些Animal的Box。box只是對堆中某些內存的引用。因為引用的大小是靜態已知的,並且編譯器可以保證引用指向已分配的堆Animal,所以我們可以從函數中返回trait。

每當在堆上分配內存時,Rust都會嘗試盡可能明確。因此,如果你的函數以這種方式返回指向堆的trait指針,則需要使用dyn關鍵字編寫返回類型,如示例2:

文件名:src/main.rs

fn random_animal(random_number: f64) -> Box<dyn Animal> {
    if random_number < 0.5 {
        Box::new(Sheep {})
    } else {
        Box::new(Cow {})
    }
}
    let random_number = 0.234;
    let animal = random_animal(random_number);
    animal.noise();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM