rust - 尝试使用 Diesel 查询时溢出评估需求 `_: Sized`

标签 rust rust-diesel

我正在尝试为我正在构建的应用程序松散地实现存储库模式,但是我似乎偶然遇到了某种递归类型定义。
在以下代码上:

use diesel::{pg::Pg, Insertable, Queryable, QueryDsl, PgConnection, Identifiable, Table};
use std::marker::PhantomData;
use anyhow::anyhow;

pub struct Repository<Entity, SqlType, Tab> {
    _entity_phantom: PhantomData<Entity>,
    _type_phantom: PhantomData<SqlType>,
    table: Tab,
}

impl <Entity, SqlType, Tab> Repository<Entity, SqlType, Tab>
where
    Entity: Queryable<SqlType, Pg> + Insertable<Tab> + Identifiable,
    Tab: Table
{
    fn find_by_id(&self, id: i64, conn: &PgConnection) -> anyhow::Result<Entity> {
        match self.table.find(id).first::<Entity>(conn) {
            Ok(entity) => Ok(entity),
            Err(e) => Err(anyhow!("{}", e)),
        }
    }
}
我得到错误:
error[E0275]: overflow evaluating the requirement `_: Sized`
  --> support/src/lib.rs:18:26
   |
18 |         match self.table.find(id).first::<Entity>(conn) {
   |                          ^^^^
   |
   = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`support`)
   = note: required because of the requirements on the impl of `FilterDsl<_>` for `<Tab as AsQuery>::Query`
我试过增加箱子顶部的递归限制,但无济于事。洒水+ Sized在整个特征范围内,似乎也没有做任何事情。
我错过了什么?

最佳答案

此类错误通常意味着 diesel由于限制不够,无法解决您的特征界限。
Diesel 泛型编程通常有点复杂,但这里有一些提示可以在下次遇到此错误时帮助您:

  • 每当您想使用特定方法时,例如 find ,你必须确保你 还有检查相同的界限!
  • 更喜欢构建特定的可重用函数,让你得到你想要的
  • 每次您调用柴油方法时,您都在“包装”一个新语句,这个新语句必须被绑定(bind),否则您会收到奇怪的错误消息,就像您的问题一样。
  • 这些方法的结果通常有一个简写形式,如 Find。或 Limit在下面的代码中
  • 正如你在第 27 行看到的,我们必须嵌套 Limit<Find<..>> ,对于您在查询链中调用的每个新方法,您都需要指定它。

  • use anyhow::anyhow;
    use diesel::{
        associations::HasTable,
        dsl::{Find, Limit},
        query_dsl::{
            methods::{FindDsl, LimitDsl},
            LoadQuery,
        },
        PgConnection, RunQueryDsl, Table,
    };
    use std::marker::PhantomData;
    
    pub struct Repository<Entity, Tab> {
        _entity_phantom: PhantomData<Entity>,
        _table_phantom: PhantomData<Tab>,
    }
    
    impl<Entity, Tab> Repository<Entity, Tab>
    where
        Entity: HasTable<Table = Tab>,
        Tab: Table,
    {
        fn find_by_id(&self, id: i64, conn: &PgConnection) -> anyhow::Result<Entity>
        where
            Tab: LimitDsl + FindDsl<i64>,
            Find<Tab, i64>: LimitDsl + Table,
            Limit<Find<Tab, i64>>: LoadQuery<PgConnection, Entity>,
        {
            match Entity::table().find(id).first::<Entity>(conn) {
                Ok(entity) => Ok(entity),
                Err(e) => Err(anyhow!("{}", e)),
            }
        }
    }
    

    What am I missing?


    一般来说,人们可以猜到你试图做什么,我不认为你没有达到预期的结果是你的错。这种泛型编程很难理解,而且有各种类型及其名称T , U很容易迷路。
  • 你的特质绑定(bind)在 Entity如果我正确理解 Entity 是错误的指:
  • Queryable<Query, Database>表示可以在 Database 中查询其实现的类型通过Query . “传入”类型 SqlQuery 没有意义如果您也不传递具体类型!

  • Insertable<Tab>我认为是其他方法的遗留物吗?
  • Identifiable也?
  • 关于rust - 尝试使用 Diesel 查询时溢出评估需求 `_: Sized`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67659872/

    相关文章:

    stream - 如何在 Rust 中将 Stream 转换为 RepeatedField?

    Rust Diesel 更新连接表

    postgresql - 如何使用 diesel-rs 选择部分色谱柱?

    mysql - 如何使用diesel和mysql调用/部署无服务器功能?

    loops - 如何检查 Vec 中的值是否为 None?

    syntax - 为什么以及何时应该在 block 的末尾使用逗号?

    rust - 无法推断 `U` 的类型

    rust - 将任何 Diesel 表作为参数传递

    unit-testing - 在 Rust 中进行单元测试后清理的好方法是什么?

    rust - 结构可以在 Rust 中实现两个具有冲突方法名称的特征吗?