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

时间:2016-01-10 08:42:12

标签: closures rust type-inference

代码如下:

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

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

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

如何告诉编译器参数的类型是一个推动Fn的泛型类型?

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

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

感谢您的回答。但这种类型推断问题令我感到困惑。使用fn可以使编译器满意。

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

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

1 个答案:

答案 0 :(得分:3)

the guidelines in the Rust book section on returning closures将闭包变成move闭包并装箱后,这就是我必须要做的才能让你的程序在the Rust Playground运行:

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

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