Rust笔记 - fn && Fn

294 阅读1分钟

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的理解: