[英]Instantiating a struct parameterized by a trait
我正在Rust中構建一個webapp,並嘗試實現基本的Rails風格的數據庫遷移來管理我的數據庫。 在我的代碼, Migration
是與性狀up
和down
的方法來應用和回滾遷移。 每個單獨的數據庫遷移都是實現遷移特征的結構。 為了以正確的順序跟蹤數據庫遷移,我構建了一個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.