为啥在将使用 Diesel 特征的函数重写为特征方法时会出现“溢出评估需求”?
Posted
技术标签:
【中文标题】为啥在将使用 Diesel 特征的函数重写为特征方法时会出现“溢出评估需求”?【英文标题】:Why do I get "overflow evaluating the requirement" when rewriting a function using Diesel's traits into a trait method?为什么在将使用 Diesel 特征的函数重写为特征方法时会出现“溢出评估需求”? 【发布时间】:2019-10-13 21:57:04 【问题描述】:我正在尝试使用 Diesel 添加分页。如果我使用函数,编译器能够检查泛型类型的边界,但如果我尝试与 trait 的实现做同样的事情,编译器就不能。
这是一个简单的工作示例:
use diesel::query_dsl::methods::LimitDsl, OffsetDsl;
pub fn for_page<T>(query: T)
where
T: OffsetDsl,
T::Output: LimitDsl,
query.offset(10).limit(10);
OffsetDsl
和
LimitDsl
是 Diesel 的特征,它提供了方法 offset
和 limit
。
当我尝试将此方法提取为特征并像这样实现它时
use diesel::query_dsl::methods::LimitDsl, OffsetDsl;
trait Paginator
fn for_page(self);
impl<T> Paginator for T
where
T: OffsetDsl,
<T as OffsetDsl>::Output: LimitDsl,
fn for_page(self)
self.offset(10).limit(10);
我收到一条不太清楚的错误消息。
error[E0275]: overflow evaluating the requirement `<Self as diesel::query_dsl::offset_dsl::OffsetDsl>::Output`
--> src/main.rs:3:1
|
3 | / trait Paginator
4 | | fn for_page(self);
5 | |
| |_^
|
= note: required because of the requirements on the impl of `Paginator` for `Self`
note: required by `Paginator`
--> src/main.rs:3:1
|
3 | trait Paginator
| ^^^^^^^^^^^^^^^
error[E0275]: overflow evaluating the requirement `<Self as diesel::query_dsl::offset_dsl::OffsetDsl>::Output`
--> src/main.rs:4:5
|
4 | fn for_page(self);
| ^^^^^^^^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `Paginator` for `Self`
note: required by `Paginator`
--> src/main.rs:3:1
|
3 | trait Paginator
| ^^^^^^^^^^^^^^^
我了解这意味着编译器无法检查T::Output
上的条件,但不清楚与具有相同条件的简单函数有什么区别。
我正在使用 Rust 1.35.0 和 Diesel 1.4。
【问题讨论】:
如果使用T::Output: LimitDsl
而不是<T as OffsetDsl>::Output: LimitDsl
是否有效?我尝试reproduce the issue in rust playground,但它似乎工作正常 - 操场上似乎不支持柴油,所以我还没有尝试用真正的库测试它
您使用的是哪个版本的 rust 以及哪个渠道?还有哪个版本的柴油?
不。 :( 我想这可能与 Diesel 定义这些特征的方式有关,但我不知道如何。
Rust 编译器中的约束求解器有时可能有点脆弱 - 另请参阅 this question on URLO 以获取另一个示例。
您可以尝试将您的实现限制为某些类型,而不是所有OffsetDsl
s? Have a look at how LimitDsl
is implemented for Table
for example - 它与您的 Paginator
类似,但在正文中定义了输出并相对于输入类型
【参考方案1】:
我无法回答为什么他们不同。我可以说重复 trait 定义的界限可以编译:
use diesel::query_dsl::methods::LimitDsl, OffsetDsl;
trait Paginator
where
Self: OffsetDsl,
Self::Output: LimitDsl,
fn for_page(self);
impl<T> Paginator for T
where
T: OffsetDsl,
T::Output: LimitDsl,
fn for_page(self)
self.offset(10).limit(10);
您可能还对extending Diesel guide 感兴趣,它讨论了如何最好地添加paginate
方法。
【讨论】:
有效!谢谢!应该自己试试。不过这有点奇怪,因为在这种情况下,我可以在 trait 定义中实现这个方法,而我根本不需要实现。感谢您的链接!我读过它,但对于我想要它完成的简单任务来说似乎有点过于复杂了。以上是关于为啥在将使用 Diesel 特征的函数重写为特征方法时会出现“溢出评估需求”?的主要内容,如果未能解决你的问题,请参考以下文章
&diesel::MysqlConnection 没有实现特征diesel::Connection
`DbConnection` 没有实现特征`diesel::Connection`
`bigdecimal::BigDecimal` 没有实现特征 `diesel::Expression`
<Struct> 没有实现特征 `diesel::Insertable<schema::trd::table>`
`diesel_geography::types::GeogPoint` 没有实现特征 `serde::Deserialize<'_>`