具有类型限制的 Rust 特征
Rust Traits with Type Bounds
我想使用 Rust 特性编写数据库的基本抽象。
pub trait Keyable {
type Key;
fn key(&self) -> &Self::Key;
}
和
// type alias for result - DbError are defined elsewhere
pub type Result<T> = Result<T, DbError>;
pub trait Database {
type Item;
fn get(&self, id: Keyable) -> Result<Self::Item>;
fn upsert(&self, item: Self::Item) -> Result<Keyable>;
}
我很难表达这一点:Database::Item 必须至少是 Keyable。
有两个用例:
- 我可以使用一些任意类型,它知道如何在我的 Database::get(k: Keyable) 函数中 return 一个 key() 而 return 一些项目(这很可能不仅仅是 key().
- 在我的 fn Database::upsert() 函数中,我希望能够使用该项目至少是 Keyable 的事实,因此访问 key() 来查找数据库以做出决定,如果我只需插入或更新。
您可以在关联类型上放置特征绑定:
pub trait Database {
type Item: Keyable;
然后,您可以在函数签名中使用该特征的关联类型:
fn get(&self, id: &<Self::Item as Keyable>::Key) -> Result<Self::Item>;
fn upsert(&self, item: Self::Item) -> Result<<Self::Item as Keyable>::Key>;
(我还添加了一个 &
因为 get()
可能不需要使用密钥数据。)
将所有内容组合成一个可编译的示例:
pub enum DbError { Something }
pub type Result<T> = std::result::Result<T, DbError>;
pub trait Keyable {
type Key;
fn key(&self) -> &Self::Key;
}
pub trait Database {
type Item: Keyable;
fn get(&self, id: &<Self::Item as Keyable>::Key) -> Result<Self::Item>;
fn upsert(&self, item: Self::Item) -> Result<<Self::Item as Keyable>::Key>;
}
我想使用 Rust 特性编写数据库的基本抽象。
pub trait Keyable {
type Key;
fn key(&self) -> &Self::Key;
}
和
// type alias for result - DbError are defined elsewhere
pub type Result<T> = Result<T, DbError>;
pub trait Database {
type Item;
fn get(&self, id: Keyable) -> Result<Self::Item>;
fn upsert(&self, item: Self::Item) -> Result<Keyable>;
}
我很难表达这一点:Database::Item 必须至少是 Keyable。
有两个用例:
- 我可以使用一些任意类型,它知道如何在我的 Database::get(k: Keyable) 函数中 return 一个 key() 而 return 一些项目(这很可能不仅仅是 key().
- 在我的 fn Database::upsert() 函数中,我希望能够使用该项目至少是 Keyable 的事实,因此访问 key() 来查找数据库以做出决定,如果我只需插入或更新。
您可以在关联类型上放置特征绑定:
pub trait Database {
type Item: Keyable;
然后,您可以在函数签名中使用该特征的关联类型:
fn get(&self, id: &<Self::Item as Keyable>::Key) -> Result<Self::Item>;
fn upsert(&self, item: Self::Item) -> Result<<Self::Item as Keyable>::Key>;
(我还添加了一个 &
因为 get()
可能不需要使用密钥数据。)
将所有内容组合成一个可编译的示例:
pub enum DbError { Something }
pub type Result<T> = std::result::Result<T, DbError>;
pub trait Keyable {
type Key;
fn key(&self) -> &Self::Key;
}
pub trait Database {
type Item: Keyable;
fn get(&self, id: &<Self::Item as Keyable>::Key) -> Result<Self::Item>;
fn upsert(&self, item: Self::Item) -> Result<<Self::Item as Keyable>::Key>;
}