trait可以有默认实现,这样可以做到类似template method的设计模式,例如
trait Stores<TModel> {fn get_by_id(&self, id: u64) -> TModel;}trait Storage {fn query<TModel>(&self, id: u64) -> TModelwhereSelf: Stores<TModel> // Self constrain{self.get_by_id(id)}}struct UserDatabase {}impl Storage for UserDatabase {}
当UserDatabase实现了Storage这个trait后,就有了query的能力,这里可以看到where约束除了可以约束泛型类型T外,还能约束 Self 这里约束了Self必须实现 Stores<TModel>, 这样在query方法中就能调用Stores 的方法,我们就能为每种类型的实现get_by_id这个方法
impl Stores<User> for UserDatabase {fn get_by_id(&self, id: u64) -> User {User{id: 123}}}impl <'a> Stores<Avatar<'a>> for UserDatabase {fn get_by_id(&self, id: u64) -> Avatar<'a> {Avatar{id: 123, url: url}}}#[derive(Debug)]struct User {id: u64,}#[derive(Debug)]struct Avatar<'a> {id: u64,url: &'a str,}
fn main() {let db = UserDatabase{};let u = db.query::<User>(1);println!("user is {:?}", u);let a = db.query::<Avatar>(2);println!("Avatar is {:?}", a);}
