这似乎是一个特定的问题,但我会尝试将其尽可能概括。可以随意编辑标题,因为我是Rust的新手,而且不知道如何简洁地表达它。
我想做的事最好通过示例来说明。
我正在使用柴油并生成schema.rs
,它定义了表Cats
和Dogs
(带有table!
宏)。
现在,我为get_all
和Cat
(我实现了2种结构)编写了Dog
个函数
pub fn get_all_cats(connection: &PgConnection) -> Vec<Cat> {
Cats
.load::<Cat>(connection)
.expect("Error")
}
pub fn get_all_dogs(connection: &PgConnection) -> Vec<Dog> {
Dogs
.load::<Dog>(connection)
.expect("Error")
}
但是,由于它们基本相同,因此我很乐意用get_all<T>
方法将其归纳。
我想创建一个特征:
trait GetAll<T=Self> {
fn get_all(conn: &PgConnection) -> Vec<T> {
Resource.load::<T>(conn)
}
}
当然,我现在需要定义Resource
或Cats
。因此,我想做一个解决方法,并定义一个方法Dogs
,可以在get_resource
和Cat
中覆盖该方法,以提供他们所尊敬的Resource。该类型为Dog
。
问题是我不知道diesel::query_dsl::RunQueryDsl<Conn>
必须实现什么类型约束(然后是该类型的类型参数,依此类推),我认为应该有一种更简单的方法来进行逆向工程整个链式柴油车。
Conn
此操作失败,显示trait GetAll<T=Self> {
fn get_resource() -> diesel::query_dsl::RunQueryDsl;
fn get_all(conn: &PgConnection) -> Vec<T> {
get_resource().load::<T>(conn)
}
}
我的方法是否有一个“修复程序”(例如,编译器自动推断类型)或设计被破坏了?如果是后者,该如何概括expected 1 type argument
方法?
PS:get_all
特性也是如此,这应该是Queryable
的约束,但同样需要2个类型参数。
答案 0 :(得分:1)
似乎您的特征需要一个关联的类型。这使您可以表达一个事实,即数据结构具有与之关联的唯一资源类型。
trait GetAll {
type Resource;
fn get_all(conn: &PgConnection) -> Vec<Self> {
Self::Resource::load::<Self>(conn)
}
}
impl GetAll for Dog {
type Resource = Dogs;
}
impl GetAll for Cat {
type Resource = Cats;
}
您应该可以这样使用:
let dogs = Dog::get_all(&conn);
let cats = Cat::get_all(&conn);