简体   繁体   English

如何在柯里化函数上实现特征?

[英]How do I implement a trait on a curried function?

If I try to implement the trait Frob for functions like foo as follows:如果我尝试为foo Frob的函数实现特征Frob如下:

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");
}

I get the error我收到错误

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<_, _, _>`

First of all, how do I interpret this error message?首先,我该如何解释这个错误信息? Second, how do I write the trait bound correctly?其次,如何正确编写 trait bound? Presumably the problem has something to do with the returned closure hanging on to state , but I can't find a place to specify a lifetime for G .据推测,问题与挂在state上的返回闭包有关,但我找不到指定G生命周期的地方。

  1. First of all, how do I interpret this error message?首先,我该如何解释这个错误信息?

    Yes, it is a tad cryptic isn't it?是的,这有点神秘,不是吗? Two things to recognise:需要认识两件事:

    • <for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo} is the compiler's very wordy way of expressing the type of function foo ; <for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}是编译器非常冗长的表达函数类型的方式foo ; and

    • the same note is repeated for that function type, a shared reference to that function type, and a mutable reference to that function type—this happens when the compiler attempts automatic referencing in method call syntax such as you have in foo.frob(...) .对于该函数类型、对该函数类型的共享引用和对该函数类型的可变引用重复相同的注释——当编译器尝试在方法调用语法中自动引用时会发生这种情况,例如在foo.frob(...) .

    So we can quickly distill the error message down to:因此,我们可以快速将错误消息提炼为:

     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<_, _, _>`

    The compiler is telling us that it found a potential frob method on {foo} but in order for it to be applicable, {foo} 's return type must match the constraints of the Frob trait (but it doesn't).编译器告诉我们它在{foo}上找到了一个潜在的frob方法,但为了使其适用, {foo}的返回类型必须匹配Frob特征的约束(但事实并非如此)。

  2. Second, how do I write the trait bound correctly?其次,如何正确编写 trait bound? Presumably the problem has something to do with the returned closure hanging on to state , but I can't find a place to specify a lifetime for G .据推测,问题与挂在state上的返回闭包有关,但我找不到指定G生命周期的地方。

    You need to add the lifetime constraint to the trait ( playground ):您需要将生命周期约束添加到 trait ( 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) } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM