推断类型构造函数的类型
Posted
技术标签:
【中文标题】推断类型构造函数的类型【英文标题】:Infer types for type constructor 【发布时间】:2019-09-23 23:43:22 【问题描述】:这似乎是一个具体的问题,但我会尽量概括它。随意编辑标题,因为我是 Rust 新手,不知道如何简洁地表达它。
我想做的最好用例子来解释。
我正在使用柴油并生成 schema.rs
,它定义了表 Cats
和 Dogs
(使用 table!
宏)。
现在我为Cat
和Dog
编写了get_all
函数(我实现了2 个结构)
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
和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
失败
我的方法是否有“修复”(例如编译器自动推断类型)或设计是否损坏?如果是后者,我该如何推广get_all
方法呢?
PS:Queryable
trait 也是如此,它应该是 T
的约束,但同样需要 2 个类型参数。
【问题讨论】:
你能提供Cat
/Cats
和Dog
/Dogs
的定义吗?
它们无关紧要,但pub Struct Cat pub id: Uuid
和pub Struct Dog pub id: Uuid
就足够了。
【参考方案1】:
您的 trait 似乎需要关联类型。这让您可以表达数据结构具有与之关联的唯一资源类型这一事实。
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);
【讨论】:
好主意,但 Resource 不是一种类型,如果我理解正确的话,它是diesel::query_dsl::RunQueryDsl
的一个实例。不过我可以做type Resource;
然后在get_resource() -> Resource
的方法签名中使用这种类型,对吧?
非虚拟机。我仍然需要告诉编译器Resource
有一个方法.load()
,所以我再次需要对其进行约束,这是我首先遇到的问题。
@KillPinguin 我认为您需要提供有关所涉及的所有类型的更多信息。以上是关于推断类型构造函数的类型的主要内容,如果未能解决你的问题,请参考以下文章