[][src]Function tao_of_rust::ch06::functions::higher_kind_function

pub fn higher_kind_function()

函数:高阶函数

Base usage: 函数作为参数

type MathOp = fn(i32, i32) -> i32;
fn math(op: MathOp, a: i32, b: i32) -> i32{
    println!("{:p}", op);
    op(a, b)
}

fn sum(a: i32, b: i32) -> i32 {
    a + b
}
fn product(a: i32, b: i32) -> i32 {
    a * b
}
fn main() {
    let (a, b) = (2, 3);
    assert_eq!(math(sum, a, b), 5);  // 传递函数指针
    assert_eq!(math(product, a, b), 6);
}Run

Base usage: 函数指针

fn hello(){
    println!("hello function pointer");
}
fn main(){
    let fn_ptr: fn() = hello;
    println!("{:p}", fn_ptr); // 0x562bacfb9f80
    let other_fn = hello;
    // println!("{:p}", other_fn);  // not function pointer
    hello();
   other_fn();
   fn_ptr();
   (fn_ptr)();
}Run

Base usage: 函数作为返回值

type MathOp = fn(i32, i32) -> i32;
fn math(op: &str) -> MathOp {
    fn sum(a: i32, b: i32) -> i32 {
        a + b
    }
    fn product(a: i32, b: i32) -> i32 {
        a * b
    }
    match op {
        "sum" => sum,
        "product" => product,
        _ => {
            println!(
                "Warning: Not Implemented {:?} oprator, Replace with sum",
                op
            );
            sum
        }
    }
}
fn main() {
   let (a, b) = (2, 3);
   let sum = math("sum");
   let product = math("product");
   let div = math("div");
   assert_eq!(sum(a, b), 5);
   assert_eq!(product(a, b), 6);
   assert_eq!(div(a, b), 5);
}Run

Base usage: 返回的函数和参与计算的参数直接绑定 会报错

fn sum(a: i32, b: i32) -> i32 {
    a + b
}
fn product(a: i32, b: i32) -> i32 {
    a * b
}
type MathOp = fn(i32, i32) -> i32;
fn math(op: &str, a: i32, b: i32) -> MathOp {
    match op {
       "sum" => sum(a, b),
       _ => product(a, b)
   }
}
fn main() {
   let (a, b) = (2, 3);
   let sum = math("sum", a, b);
}Run

Base usage: 计数函数,默认加一

fn counter() -> fn(i32) -> i32 {
    fn inc(n: i32) -> i32 {
        n + 1
    }
    inc
}
fn main() {
    let f = counter();
    assert_eq!(2, f(1));
}Run

Base usage: 计数函数,指定默认增长值i

会出错,因为函数不能捕捉动态环境中的变量i,需要闭包才可以

fn counter(i: i32) -> fn(i32) -> i32 {
    fn inc(n: i32) -> i32 {
        n + i  // error[E0434]: can't capture dynamic environment in a fn item
    }
    inc
}
fn main() {
    let f = counter(2);
    assert_eq!(3, f(1));
}Run