我想写一个接受闭包的i32-returning 函数
接受零个参数,一个闭包接受一个参数,和一个闭包
采用两个参数,其中所有闭包参数的类型均为 i32 和
每个闭包都返回f32。
该函数的签名会是什么样子?
看起来像这样:
fn closures<F1, F2, F3>(mut f1: F1, mut f2: F2, mut f3: F3) -> i32
where
F1: FnMut() -> f32,
F2: FnMut(i32) -> f32,
F3: FnMut(i32, i32) -> f32,
{
(f1() + f2(10) + f3(20, 30)) as i32
}
fn main() {
let x = closures(|| 0.1, |x| (2 * x) as f32, |x, y| (x + y) as f32);
println!("{}", x);
}
如果你想强制调用者传递不改变环境的闭包,你可以使用Fn而不是FnMut(并在f1、f2和f3之前删除mut) ,但总的来说,我认为你会想要使用FnMut。
此代码使用未装箱的闭包糖和重载调用。没有它们,它看起来像这样:
#![feature(unboxed_closures, fn_traits)]
fn closures<F1, F2, F3>(mut f1: F1, mut f2: F2, mut f3: F3) -> i32
where
F1: FnMut<(), Output = f32>,
F2: FnMut<(i32,), Output = f32>,
F3: FnMut<(i32, i32), Output = f32>,
{
(f1.call_mut(()) + f2.call_mut((10,)) + f3.call_mut((20, 30))) as i32
}
fn main() {
let x = closures(|| 0.1, |x| (2 * x) as f32, |x, y| (x + y) as f32);
println!("{}", x);
}
糖用于美化闭包类型语法,重载调用功能允许省略显式call_* 方法。
Rust 1.0 之前
编者注这个问题是在 Rust 1.0 之前提出的,本节仅适用于从那时到 1.0 之间发生的变化。
至于未来会发生什么变化,那么闭包构造语法很可能会被简化(当当前的闭包被丢弃时),所以main()位将从这里改变:
fn main() {
let x = closures(
|&mut:| 0.1,
|&mut: x: int| (2*x) as f32,
|&mut: x: int, y: int| (x + y) as f32
);
println!("{}", x);
}
看起来像这样:
fn main() {
let x = closures(
|| 0.1,
|x| (2*x) as f32,
|x, y| (x + y) as f32
);
println!("{}", x);
}
将推断闭包的实际类型(FnMut、Fn 或 FnOnce)。
还会有其他更改,例如用于从函数返回的闭包的 move 关键字(move 影响变量捕获语义)。 this 接受的 RFC 涵盖了这一点。
一般来说,未装箱的闭包在this RFC 中进行了概述。但是,它没有更新,包括新的闭包糖语法和其他细微的变化;最好关注 Rust issue tracker 以了解更多信息。例如,很多未装箱闭包的问题都汇总在this 错误中。