我想编写一个int-returning函数,它接受一个带零参数的闭包,一个带一个参数的闭包,一个带两个参数的闭包,其中所有闭包参数都是类型int,每个闭包返回f32.
这个函数的签名是什么样的?
现在我想接受通过Fn和FnMut特征.签名是什么样的?是否需要使用箱子中的功能?如果是这样,哪些是为什么?
如果知道:它看起来像糖?脱?
如果知道:未来可能会发生什么变化?
Vla*_*eev 10
我想编写一个int返回函数,它接受一个带零参数的闭包,一个带一个参数的闭包,一个带两个参数的闭包,其中所有闭包参数都是int类型,每个闭包都返回f32.
这个函数的签名是什么样的?
功能签名及其使用目前(2014-10-26每晚)可能如下所示:
#![feature(unboxed_closures, unboxed_closure_sugar, overloaded_calls)]
fn closures<F1, F2, F3>(mut f1: F1, mut f2: F2, mut f3: F3) -> int
where F1: FnMut() -> f32,
F2: FnMut(int) -> f32,
F3: FnMut(int, int) -> f32 {
(f1() + f2(10) + f3(20, 30)) as int
}
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);
}
Run Code Online (Sandbox Code Playgroud)
如果你想强制调用者传递不会改变他们环境的闭包,你可以使用Fn而不是FnMut(和mut之前删除f1,f2和f3),但一般来说,我想,你会想要使用FnMut.
此代码使用未装箱的封闭糖和重载调用.没有它们,它看起来像这样:
#![feature(unboxed_closures)]
fn closures<F1, F2, F3>(mut f1: F1, mut f2: F2, mut f3: F3) -> int
where F1: FnMut<(), f32>,
F2: FnMut<(int,), f32>,
F3: FnMut<(int, int), f32> {
(f1.call_mut(()) + f2.call_mut((10,)) + f3.call_mut((20, 30))) as int
}
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);
}
Run Code Online (Sandbox Code Playgroud)
糖用于美化闭包类型语法,而重载调用功能允许省略显式call_*方法.
至于将来会发生什么变化,那么闭包构造语法很可能会被简化(当前的闭包被删除),所以这个main()位看起来像这样:
fn main() {
let x = closures(
|| 0.1,
|x| (2*x) as f32,
|x, y| (x + y) as f32
);
println!("{}", x);
}
Run Code Online (Sandbox Code Playgroud)
将推断闭包的实际类型(FnMut,Fn或FnOnce).
还会有其他更改,例如move从函数返回的闭包关键字(move影响变量捕获语义).这被这个公认的RFC 所涵盖.
通常,此 RFC 中概述了未装箱的闭包.但是,它没有更新,因为新的闭包糖语法和其他微妙的变化; 最好关注Rust 问题跟踪器以了解更多相关信息.例如,在此错误中聚合了许多未装箱的闭包问题.
Fn,FnMut并且FnOnce是随未装箱闭包引入的三种特征类型。除了它们单个方法的名称之外,这些特征之间的区别在于这些方法上的self参数传递方式不同:
Fn:(&self通过引用,不能改变闭包的环境)FnMut:(&mut self通过引用,可以改变闭包的环境)FnOnce:(self按值,消耗闭包,所以不能多次调用闭包)这些 trait 有一个类型参数 ,Args它是一个元组类型,表示闭包的参数(或者()如果闭包没有参数)。FnOnce有关联的 type Result,它是闭包的返回类型。Fn是 的子特征FnMut,并且FnMut是 的子特征FnOnce,这意味着Fn并且FnMut“继承”Result自FnOnce。未装箱的闭包自动实现适用的特征。
fn foo<F: Fn() -> f32>(closure: F) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
fn foo<F: Fn(i32) -> f32>(closure: F) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
fn foo<F: Fn(i32, i32) -> f32>(closure: F) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
where子句其中每一个也可以使用以下where语法:
fn foo<F>(closure: F) -> i32
where
F: Fn() -> f32,
{
0
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
impl trait语法:fn foo_impl(closure: impl Fn() -> f32) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
这种格式不稳定,每个例子都需要使用特征门#![feature(unboxed_closures)]。您也可以使用whereorimpl trait语法。
也可以看看:
fn foo<F: Fn<(), Output = f32>>(closure: F) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
fn foo<F: Fn<(i32,), Output = f32>>(closure: F) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
fn foo<F: Fn<(i32, i32), Output = f32>>(closure: F) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
在提出这个问题时存在“盒装”闭包,但它们在 Rust 1.0 之前被删除。
这个元错误跟踪了未装箱的闭包的发展。
| 归档时间: |
|
| 查看次数: |
7921 次 |
| 最近记录: |