在 Rust 中,我可以 return FnMut 使用捕获的可变引用,也许通过指定通用生命周期吗?

In Rust, can I return FnMut with a captured mutable reference, perhaps by specifying a generic lifetime?

是否可以在 Rust 中为这样的函数指定 FnMut 的通用生命周期?

fn f1<'a, FRet:'a + FnMut() -> ()>(v: &'a mut i32) -> FRet {
   let mut fret = || {
       let i = v;
       println!("inside");
       // lots of complicated logic on captured var
       *i = 5;
   };

   return fret;
}

现在我收到一个错误,return 与 FRet 不兼容。

您的代码有几个问题。一是你不能使 return 闭包的函数具有通用 return 类型。 f1FRet 更通用意味着调用者可以选择 FRet,当您 return 实现闭包时,这显然行不通,并且不是调用者指定的东西。这就是编译器抱怨 FRet 与您实际 return 不兼容的原因。

return 闭包的方法是将其装箱或使用 impl Trait return 类型声明一个未命名类型 return 由函数编辑:

fn f1(v: &mut i32) -> impl FnMut() {
   let fret = || {
       let i = v;
       println!("inside");
       // lots of complicated logic on captured var
       *i = 5;
   };

   fret
}

以上代码仍然无法编译,编译器抱怨闭包是 FnOnce 而不是 FnMut。这是因为 &mut i32 不是 Copy,所以 let i = v 实际上将引用移出了 v,这使得闭包只能调用一次。这可以通过重新借用来解决,即将 let i = v 更改为 let i = &mut *v

之后编译器会抱怨引用的生命周期没有被闭包捕获,你可以通过添加 + '_ 来解决这个问题。 (这等效于声明生命周期 'a 并声明 v: &'a mut i32impl FnMut() + 'a。)通过此更改,代码编译:

fn f1(v: &mut i32) -> impl FnMut() + '_ {
   let fret = || {
       let i = &mut *v;
       println!("inside");
       // lots of complicated logic on captured var
       *i = 5;
   };

   fret
}

Playground