如何返回特征的实例?

时间:2016-01-10 17:33:26

标签: rust

我正在研究a SQL migration tool。 现在我只支持Postgresql,但我想添加Mysql等。

我有以下特征,司机需要实施:

pub trait Driver {
    fn ensure_migration_table_exists(&self);
    fn remove_migration_table(&self);
    fn get_current_number(&self) -> i32;
    fn set_current_number(&self, number: i32);
    fn migrate(&self, migration: String, number: i32) -> MigrateResult<()>;
}

我想创建一个函数get_driver,它具有以下概念定义fn get_driver(url: &str) -> MigrateResult<Driver>

根据一个月前对IRC的讨论,这显然是不可能的。我之前的最佳猜测失败了:

fn get_driver<T: Driver + Sized>(url: &str) -> MigrateResult<T>

expected `core::result::Result<T, errors::MigrateError>`,
found `core::result::Result<drivers::pg::Postgres, errors::MigrateError>`

(预期的类型参数,     找到了结构drivers::pg::Postgres)[E0308]

有什么方法可以解决这个问题吗?

full code is available

1 个答案:

答案 0 :(得分:3)

在此功能中:

fn get_driver<T: Driver + Sized>(url: &str) -> MigrateResult<T>

T类型参数。它由函数的调用者选择。

看起来您希望根据url的值返回其他类型。但Rust是静态类型的:代码中任何一点的任何表达式的类型都需要在编译时知道。 (即使泛型在使用时也会专门针对具体类型。)处理这个问题的方法是使用特征对象:

例如,在:

fn get_driver(url: &str) -> MigrateResult<Box<Driver>>

Box<Driver>是一个胖指针,由一个指向该值的指针和一个指向虚拟调用表的指针组成,用于实现{的具体类型{1}}特质。该vtable包含指向每个特征方法的代码的指针。

http://doc.rust-lang.org/book/trait-objects.html

了解详情
相关问题