【问题标题】: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&lt;T&gt; 方法概括它们。

我想创造一个特质:

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&lt;Conn&gt; 类型。

问题是我不知道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 } 就足够了。

标签: rust traits associated-types rust-diesel


【解决方案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() -&gt; Resource 的方法签名中使用这种类型,对吧?
  • 非虚拟机。我仍然需要告诉编译器Resource 有一个方法.load(),所以我再次需要对其进行约束,这是我首先遇到的问题。
  • @KillPinguin 我认为您需要提供有关所涉及的所有类型的更多信息。
猜你喜欢
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-31
  • 1970-01-01
  • 2022-01-26
  • 2019-09-03
  • 1970-01-01
相关资源
最近更新 更多