如何使用一个闭包作为另一个闭包的参数?

F00*_*001 5 closures type-inference rust

代码如下:

fn main() {
  let arg = | | println!("closure");
  let call_twice = | c | { c(); c(); };
  call_twice(arg);
}
Run Code Online (Sandbox Code Playgroud)

但是编译器无法推断出参数的正确类型c。错误信息:

error: the type of this value must be known in this context

我如何告诉编译器参数的类型是泛型类型,它 impls Fn


编辑:如果参数类型是特征对象,则代码可以被编译器接受。但间接是没有必要的,是吗?

fn main() {
  let arg = | | println!("closure");
  let call_twice = | c :&Fn() | { c(); c(); };
  call_twice(&arg);
}
Run Code Online (Sandbox Code Playgroud)

感谢您的回答。但让我困惑的是类型推断问题。使用 anfn可以使编译器满意。

fn main() {
 let arg = | | println!("closure");

 // now compiler knows the argument `c` is a closure
 fn call_twice<F>(c: F) where F:Fn() {c(); c();}

 call_twice(arg);
}
Run Code Online (Sandbox Code Playgroud)

我们可以添加一个语法来支持类似的功能吗?比如for<F> | c:F | where F:Fn() {c(); c();}

Jud*_*eek 3

遵循Rust 书籍部分中有关返回闭包的指南,将闭包转换为move闭包并将其装箱,这就是我必须做的才能让您的程序在Rust Playground上运行:

fn main() {
    let arg = Box::new(move || println!("closure"));
    let call_twice = |c: Box<Fn()>| { c(); c(); };
    call_twice(arg);
}
Run Code Online (Sandbox Code Playgroud)

编辑以解决OP的最新编辑:不。您正在处理的问题最终不是类型推断问题。如果这只是类型推断,那么我们所要做的就是告诉闭包这c是一个闭包。实际问题是“闭包参数必须是局部变量,并且所有局部变量的大小必须在编译时已知。” 另一方面,Rust 函数参数显然没有这个要求。

  • 在这里,“移动”是不必要的。 (3认同)