函数指针
通过函数指针能够将函数作为参数传递给另一个函数。
函数指针的类型为小写的fn,避免与闭包的Fn混淆,用法与闭包类似:
fn add_one(x: i32) -> i32 {
x + 1
}
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
f(arg) + f(arg)
}
fn main() {
let answer = do_twice(add_one, 5);
println!("The answer is: {}", answer);
}fn 是一个类型而不是一个 trait,所以直接指定 fn 作为参数而不是声明一个带有 Fn 作为 trait bound 的泛型参数。
函数指针实现了三个闭包trait,Fn,FnMut,FnOnce,所以期望闭包的参数也可以传递函数指针。所以更加推荐编写使用泛型和闭包trait的函数,这样闭包和函数指针都能够进行传递。
如果只期望接受fn而不接受闭包,这是希望与不存在闭包的外部代码交互。比如C语言不支持闭包。
元组结构体和元组结构体枚举成员,其实被实现为返回根据参数构造的示例的函数,称为实现了闭包trait的函数指针,例如下面的调用形式:
fn main() {
enum Status {
Value(u32),
Stop,
}
let list_of_statuses: Vec<Status> = (0u32..20).map(Status::Value).collect();
}Status::Value被作为构造示例的函数使用。
返回闭包
闭包是trait,是不能直接返回的。因为它们没有可返回的具体类型,Rust 并不知道需要多少空间来储存闭包。
通过如下的方式解决:
fn returns_closure() -> Box<dyn Fn(i32) -> i32> {
Box::new(|x| x + 1)
}