我想写一个i32
返回函数,它接受一个包含零个参数的闭包、一个包含一个参数的闭包和一个包含两个参数的闭包,其中所有闭包参数都是i32
类型,每个闭包返回f32
.
那个函数的签名会是什么样子?
我想通过Fn
和FnMut
个特征来接受这些.签名是什么样子的?是否需要使用 crate 中的功能?如果是的话,是哪些,为什么?
如果知道:它看起来像什么糖?脱糖衣?
如果已知:future 可能会发生什么变化?
我想写一个i32
返回函数,它接受一个包含零个参数的闭包、一个包含一个参数的闭包和一个包含两个参数的闭包,其中所有闭包参数都是i32
类型,每个闭包返回f32
.
那个函数的签名会是什么样子?
我想通过Fn
和FnMut
个特征来接受这些.签名是什么样子的?是否需要使用 crate 中的功能?如果是的话,是哪些,为什么?
如果知道:它看起来像什么糖?脱糖衣?
如果已知:future 可能会发生什么变化?
我想写一个接受闭包的
i32
返回函数那个函数的签名会是什么样子?
看起来是这样的:
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);
}
sugar用于修饰闭包类型语法,重载调用特性允许省略显式的call_*
个方法.
Editor's note这个问题是在Rust 1.0之前提出的,本节仅适用于在Rust 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了解更多信息.例如,许多与未绑定闭包有关的问题都聚集在一起.