Generics 使用柴油机的通用函数会导致溢出

Generics 使用柴油机的通用函数会导致溢出,generics,rust,Generics,Rust,我有一个用Rust编写的API,它的目标是在一个数据库中公开15个表。我已经编写了几个非常相似的函数来公开每个表,所以我想我应该尝试一下多态性来简化代码 我已将所有代码简化为一个文件: #[macro_use] extern crate diesel; extern crate dotenv; extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; table! { tab

我有一个用Rust编写的API,它的目标是在一个数据库中公开15个表。我已经编写了几个非常相似的函数来公开每个表,所以我想我应该尝试一下多态性来简化代码

我已将所有代码简化为一个文件:

#[macro_use]
extern crate diesel;
extern crate dotenv;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

table! {
    table1 (id) {
        id -> Int4,
        value -> Text,
    }
}

table! {
    table2 (id) {
        id -> Int4,
        value -> Text,
    }
}

#[derive(Identifiable, Queryable, Serialize)]
#[table_name = "table1"]
struct Model1 {
    pub id: i32,
    pub value: String,
}

#[derive(Identifiable, Queryable, Serialize)]
#[table_name = "table2"]
struct Model2 {
    pub id: i32,
    pub value: String,
}

use dotenv::dotenv;
use std::env;

fn get_connection() -> PgConnection {
    dotenv().ok();
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    PgConnection::establish(&database_url).expect("Database not working")
}

use diesel::QueryDsl;
use diesel::pg::PgConnection;
use diesel::query_dsl::LoadQuery;
use diesel::result::Error;
use diesel::query_dsl::filter_dsl::FindDsl;
use serde::Serialize;
use serde_json::to_string;

fn get_row<'a, Model, Table>(table: Table, id: i32) -> Result<String, Error>
where
    Table: QueryDsl,
    <Table as FindDsl<i32>>::Output: LoadQuery<PgConnection, Model>,
    Model: Serialize,
{
    let result: Model = table.find(id).load(&get_connection())?;
    Ok(to_string(&result)?)
}

fn main() {
    let row1 = get_row::<Model1, _>(table1::table, 1);
    let row2 = get_row::<Model2, _>(table2::table, 1);
}
当我尝试运行此程序时,出现以下编译器错误:

error[E0275]:溢出评估需求`::Output`
-->src/main.rs:54:1
|
54 |/fn滚你离得不远:

use diesel::dsl::Find;
use diesel::pg::PgConnection;
use diesel::query_dsl::{LoadQuery, RunQueryDsl};
use diesel::query_dsl::filter_dsl::FindDsl;
use diesel::result::Error;

fn get_row<'a, Model, Table>(table: Table, id: i32) -> Result<String, Error>
where
    Table: FindDsl<i32>,
    Find<Table, i32>: LoadQuery<PgConnection, Model>,
{
    let conn = get_connection();
    let result = table.find(id).load::<Model>(&conn)?;
    unimplemented!()
}
  • load
    的返回值是结果的
    Vec
    ,但您已将该类型注释为单个值。也许您想使用
    get\u result
    first
    来代替

  • 我删除了Serde特定的代码,因为没有明显的方法将Serde错误转换为Diesel错误;这取决于你


  • 感谢您提供了一个合理的、小的、完整的示例。谢谢!我按照你的建议换了一个结果。这确实更有意义:)
    use diesel::dsl::Find;
    use diesel::pg::PgConnection;
    use diesel::query_dsl::{LoadQuery, RunQueryDsl};
    use diesel::query_dsl::filter_dsl::FindDsl;
    use diesel::result::Error;
    
    fn get_row<'a, Model, Table>(table: Table, id: i32) -> Result<String, Error>
    where
        Table: FindDsl<i32>,
        Find<Table, i32>: LoadQuery<PgConnection, Model>,
    {
        let conn = get_connection();
        let result = table.find(id).load::<Model>(&conn)?;
        unimplemented!()
    }
    
    fn find<PK>(self, id: PK) -> Find<Self, PK>
    where
        Self: FindDsl<PK>,