簡體   English   中英

實例化由特征參數化的結構

[英]Instantiating a struct parameterized by a trait

我正在Rust中構建一個webapp,並嘗試實現基本的Rails風格的數據庫遷移來管理我的數據庫。 在我的代碼, Migration是與性狀updown的方法來應用和回滾遷移。 每個單獨的數據庫遷移都是實現遷移特征的結構。 為了以正確的順序跟蹤數據庫遷移,我構建了一個MigrationIndex類。

struct MigrationIndex<T> {
    migrations: Vec<Box<T>>
}
impl <T: Migration> MigrationIndex<T> {
    // methods for managing the migrations...
}

impl <T: Migration> Default for MigrationIndex<T> {
    pub fn default() -> MigrationIndex<T> {
        MigrationIndex {
            migrations: vec![]
        }
    }
}

所以我去上課:

let migrations: MigrationIndex = Default::default();

但是這行上的編譯錯誤wrong number of type arguments: expected 1, found 0 所以我嘗試添加缺少的特征參數:

let migrations: MigrationIndex<Migration> = Default::default();

但是在那一行上,編譯器將Migration解釋為一種類型,而不是一種特征,並且再次無法編譯。 猜測我試過了:

let migrations: MigrationIndex<T: Migration> = Default::default();

但最終會出現語法錯誤。 現在我很難過。 如果某個類型由特征參數化,那么在實例化時如何指定該特征?

為泛型類型參數指定值時,它必須是具體類型,而不是特征:

trait Migration {}

struct Foo;
impl Migration for Foo {}

fn main() {
    let migrations: MigrationIndex<Foo> = Default::default();
}

使用泛型時,泛型參數必須是單個具體類型。 這將導致遷移Vec中的所有對象具有相同的類型。 根據你的描述,這聽起來並不像你想要的那樣。 您想要一個實現相同特征的不同類型的Vec 這不需要泛型:

#[derive(Default)]
struct MigrationIndex {
    migrations: Vec<Box<Migration>>
}
impl MigrationIndex {
    // methods for managing the migrations...
}

我還冒昧地通過derive屬性用等效的自動生成的替換你的手動Default impl。

實際上,在您之前的實現中, Box完全沒有必要。 如果您具有具體類型,則可以直接創建該類型的Vec元素。 只有當你想要放入實現相同特征的不同類型時才需要Box ,因為這些類型可能有不同的大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM