rust - 如何在柯里化函数上实现特征?
问题描述
如果我尝试为如下Frob
函数实现特征:foo
fn foo<'b>(state: &'b mut i32) -> impl FnMut(&str) -> i32 + 'b {
move |i| *state
}
trait Frob<S, I, O> {
fn frob(self, state: &mut S, input: I) -> O;
}
impl<S, I, O, F, G> Frob<S, I, O> for F
where
F: FnMut(&mut S) -> G,
G: FnMut(I) -> O,
{
fn frob(mut self, state: &mut S, input: I) -> O {
self(state)(input)
}
}
fn bar() {
foo.frob(&mut 1, "hi");
}
我得到错误
error[E0599]: the method `frob` exists for fn item `for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}`,
but its trait bounds were not satisfied
...
= note: the following trait bounds were not satisfied:
`<for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo} as FnOnce<(&mut _,)>>::Output = _`
which is required by `for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}: Frob<_, _, _>`
`<&for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo} as FnOnce<(&mut _,)>>::Output = _`
which is required by `&for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}: Frob<_, _, _>`
`<&mut for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo} as FnOnce<(&mut _,)>>::Output = _`
which is required by `&mut for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}: Frob<_, _, _>`
首先,我该如何解释这个错误信息?其次,如何正确编写特征绑定?大概这个问题与返回的闭包挂在 上有关state
,但我找不到一个地方来指定G
.
解决方案
-
首先,我该如何解释这个错误信息?
是的,这有点神秘,不是吗?有两点需要识别:
<for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}
是编译器非常罗嗦的表达函数类型foo
的方式;和对于该函数类型、对该函数类型的共享引用和对该函数类型的可变引用重复相同的注释——当编译器尝试在方法调用语法中自动引用时会发生这种情况,例如您在
foo.frob(...)
.
因此,我们可以快速将错误消息提炼为:
error[E0599]: the method `frob` exists for fn item `{foo}`, but its trait bounds were not satisfied ... = note: the following trait bounds were not satisfied: `<{foo} as FnOnce<(&mut _,)>>::Output = _` which is required by `{foo}: Frob<_, _, _>`
编译器告诉我们它找到了一个潜在的
frob
方法,{foo}
但为了使其适用,{foo}
的返回类型必须匹配特征的约束Frob
(但它不匹配)。 -
其次,如何正确编写特征绑定?大概这个问题与返回的闭包挂在 上有关
state
,但我找不到一个地方来指定G
.您需要将生命周期约束添加到特征(playground):
trait Frob<'b, S, I, O> { fn frob(self, state: &'b mut S, input: I) -> O; } impl<'b, S: 'b, I, O, F, G> Frob<'b, S, I, O> for F where F: FnMut(&'b mut S) -> G, G: 'b + FnMut(I) -> O, { fn frob(mut self, state: &'b mut S, input: I) -> O { self(state)(input) } }
推荐阅读
- c++ - '*' 标记问题之前的预期主表达式
- javascript - 功能作为反应孩子无效?- 需要帮助将提取的数据提取到表中
- c# - XmlSerializer 序列化错误与 IIS/ASP.NET 中的继承类型但在桌面 .NET 应用程序中没有
- php - 当我需要同时显示帖子数据时,如何防止表单重新提交?
- docker - 运行容器后无法访问气流网络服务器
- powershell - 您能否帮助我使用脚本(在 Powershell 上制作)来删除超过 5 天的特定文件夹的文件(最终是子文件夹)?
- netlify - 网站不会部署使用 blogdown 创建的 hugo-academic 主题
- sql - 如何在 SELECT 语句中重命名和引用 COUNT(*)?
- assembly - 如何一次性使用8051的所有寄存器组?
- dart - sqflite 中的多个表