How do I write a function that can compose `FnMut`

2019-09-11 12:23发布

问题:

Here's a compose function that can compose Fn closures:

fn compose<'a, T1, T2, T3, F1, F2>(f: F1, g: F2) -> Box<Fn(T1) -> T3 + 'a>
    where F1: Fn(T1) -> T2 + 'a,
          F2: Fn(T2) -> T3 + 'a
{
    box move |x| g(f(x))
}

How do I make it so that this compose function can take FnMut closures? I tried:

fn compose<'a, T1, T2, T3, F1, F2>(f: F1, g: F2) -> Box<FnMut(T1) -> T3 + 'a>
    where F1: FnMut(T1) -> T2 + 'a,
          F2: FnMut(T2) -> T3 + 'a
{
    box move |x| g(f(x))
}

But it complains about:

error: cannot borrow captured outer variable in an `FnMut` closure as mutable
         box move |x| g(f(x))
                      ^
error: cannot borrow captured outer variable in an `FnMut` closure as mutable
         box move |x| g(f(x))
                        ^

Extending this, can it be made to work with FnOnce closures?

回答1:

Local variables f and g must be mutable:

fn compose<'a, T1, T2, T3, F1, F2>(mut f: F1, mut g: F2) -> Box<FnMut(T1) -> T3 + 'a>
    where F1: FnMut(T1) -> T2 + 'a,
          F2: FnMut(T2) -> T3 + 'a
{
    Box::new(move |x| g(f(x)))
}


标签: closures rust