fn是函数类型,看一个实例:
fn f(mut index: i32) -> i32 {
index += 1;
index
}
fn add_one(f: fn(i32) -> i32, index: i32) -> i32 {
f(index)
}
fn main() {
assert_eq!(add_one(f, 1), 2);
}
Fn 是 trait ,包括函数和闭包。定义如下:
trait Fn() -> R {
fn call(&self) -> R;
}
fn f(mut index: i32) -> i32 {
index += 1;
index
}
fn add_two<F>(f: F, index: i32) -> i32
where
F: Fn(i32) -> i32,
{
f(index)
}
fn main() {
let i = 1;
let fp = move |mut index: i32| -> i32 {
index += i;
index
};
assert_eq!(add_two(f, 1), 2);
assert_eq!(add_two(fp, 1), 2);
}
fnMut可以引入可变环境变量,定义如下:
trait FnMut() -> R {
fn call_mut(&mut self) -> R;
}
fn add<F>(mut f: F, index: i32) -> i32
where
F: FnMut(i32) -> i32,
{
f(index)
}
fn main() {
let mut i = 1;
let fp = |mut index: i32| -> i32 {
i += 1;
index += i;
index
};
assert_eq!(add(fp, 1), 3);
assert_eq!(i, 2);
}
FnOnce定义函数只能被调用一次,定义如下:
trait FnOnce() -> R {
fn call_once(self) -> R;
}
fn add<F>(f: F, index: i32) -> i32
where
F: FnOnce(i32) -> i32,
{
f(index)
}
fn main() {
let mut i = 1;
let fp = |mut index: i32| -> i32 {
i += 1;
index += i;
index
};
assert_eq!(add(fp, 1), 3);
assert_eq!(i, 2);
}
下面看一张图加深对三个trait的理解:
