Skip to content

高级函数

> 探索函数指针、高阶函数等进阶特性,为后续闭包和迭代器学习打基础。

完整示例

示例 1:简单计算器

rust
fn main() {
    println!("=== 简单计算器 ===\n");

    let a = 10.0;
    let b = 3.0;

    println!("a = {}, b = {}", a, b);
    println!("{:-^30}", "");

    println!("a + b = {}", add(a, b));
    println!("a - b = {}", subtract(a, b));
    println!("a * b = {}", multiply(a, b));

    match divide(a, b) {
        Some(result) => println!("a / b = {}", result),
        None => println!("a / b = 错误:除数为零"),
    }

    // 测试除零
    match divide(10.0, 0.0) {
        Some(result) => println!("10 / 0 = {}", result),
        None => println!("10 / 0 = 错误:除数为零"),
    }
}

fn add(a: f64, b: f64) -> f64 {
    a + b
}

fn subtract(a: f64, b: f64) -> f64 {
    a - b
}

fn multiply(a: f64, b: f64) -> f64 {
    a * b
}

fn divide(a: f64, b: f64) -> Option<f64> {
    if b == 0.0 {
        None
    } else {
        Some(a / b)
    }
}
▶ Run

输出:

=== 简单计算器 ===

a = 10.0, b = 3.0
------------------------------
a + b = 13
a - b = 7
a * b = 30
a / b = 3.3333333333333335
10 / 0 = 错误:除数为零

示例 2:学生成绩管理

rust
fn main() {
    // 学生数据
    let students = vec![
        ("张三", 85.0, 90.0, 78.0),
        ("李四", 92.0, 88.0, 95.0),
        ("王五", 78.0, 82.0, 80.0),
    ];

    println!("╔════════════════════════════════════════╗");
    println!("║           学生成绩单                    ║");
    println!("╠════════════════════════════════════════╣");

    for (name, chinese, math, english) in &students {
        let avg = calculate_average(*chinese, *math, *english);
        let grade = get_grade(avg);

        println!("║ {} | 语文:{:.0} 数学:{:.0} 英语:{:.0} | 平均:{:.1} {} ║",
                 name, chinese, math, english, avg, grade);
    }

    println!("╚════════════════════════════════════════╝");
}

fn calculate_average(c: f64, m: f64, e: f64) -> f64 {
    (c + m + e) / 3.0
}

fn get_grade(average: f64) -> &'static str {
    match average {
        a if a >= 90.0 => "优秀",
        a if a >= 80.0 => "良好",
        a if a >= 70.0 => "中等",
        a if a >= 60.0 => "及格",
        _ => "不及格",
    }
}
▶ Run

示例 3:字符串处理工具

rust
fn main() {
    let text = String::from("  Hello, Rust World!  ");

    println!("原文本:'{}'", text);
    println!("{:-^40}", "");
    println!("去除空白:'{}'", trim_string(&text));
    println!("大写:'{}'", to_uppercase_string(&text));
    println!("小写:'{}'", to_lowercase_string(&text));
    println!("单词数:{}", count_words(&text));
    println!("字符数(不含空白):{}", count_chars_no_space(&text));
}

fn trim_string(s: &str) -> &str {
    s.trim()
}

fn to_uppercase_string(s: &str) -> String {
    s.to_uppercase()
}

fn to_lowercase_string(s: &str) -> String {
    s.to_lowercase()
}

fn count_words(s: &str) -> usize {
    s.split_whitespace().count()
}

fn count_chars_no_space(s: &str) -> usize {
    s.chars().filter(|c| !c.is_whitespace()).count()
}
▶ Run

返回多个值

使用元组

rust
fn main() {
    let numbers = [3, 1, 4, 1, 5, 9, 2, 6];
    let (min, max) = find_min_max(&numbers);
    println!("最小值:{},最大值:{}", min, max);
}

fn find_min_max(numbers: &[i32]) -> (i32, i32) {
    let mut min = numbers[0];
    let mut max = numbers[0];

    for &n in numbers.iter() {
        if n < min {
            min = n;
        }
        if n > max {
            max = n;
        }
    }

    (min, max)  // 返回元组
}
▶ Run

使用结构体(更清晰)

rust
struct Statistics {
    min: i32,
    max: i32,
    sum: i32,
    count: usize,
    average: f64,
}

fn calculate_statistics(numbers: &[i32]) -> Statistics {
    let min = *numbers.iter().min().unwrap();
    let max = *numbers.iter().max().unwrap();
    let sum: i32 = numbers.iter().sum();
    let count = numbers.len();
    let average = sum as f64 / count as f64;

    Statistics {
        min,
        max,
        sum,
        count,
        average,
    }
}

fn main() {
    let numbers = [3, 1, 4, 1, 5, 9, 2, 6];
    let stats = calculate_statistics(&numbers);

    println!("统计结果:");
    println!("  最小值:{}", stats.min);
    println!("  最大值:{}", stats.max);
    println!("  总和:{}", stats.sum);
    println!("  数量:{}", stats.count);
    println!("  平均:{:.2}", stats.average);
}
▶ Run

函数作为参数和返回值

函数指针

rust
fn add(a: i32, b: i32) -> i32 {
    a + b
}

fn subtract(a: i32, b: i32) -> i32 {
    a - b
}

fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

// 接受函数指针作为参数
fn calculate(op: fn(i32, i32) -> i32, a: i32, b: i32) -> i32 {
    op(a, b)
}

fn main() {
    // 函数名会自动转换为函数指针
    println!("10 + 5 = {}", calculate(add, 10, 5));
    println!("10 - 5 = {}", calculate(subtract, 10, 5));
    println!("10 * 5 = {}", calculate(multiply, 10, 5));

    // 存储函数指针
    let operations: [fn(i32, i32) -> i32; 3] = [add, subtract, multiply];

    for (i, op) in operations.iter().enumerate() {
        println!("操作 {}: {}(10, 5) = {}", i, get_op_name(i), op(10, 5));
    }
}

fn get_op_name(index: usize) -> &str {
    match index {
        0 => "add",
        1 => "subtract",
        2 => "multiply",
        _ => "unknown",
    }
}
▶ Run

返回函数指针

rust
fn add(a: i32, b: i32) -> i32 { a + b }
fn subtract(a: i32, b: i32) -> i32 { a - b }

// 根据条件返回不同的函数
fn get_operation(use_add: bool) -> fn(i32, i32) -> i32 {
    if use_add {
        add
    } else {
        subtract
    }
}

fn main() {
    let op = get_operation(true);
    println!("5 + 3 = {}", op(5, 3));  // 8

    let op = get_operation(false);
    println!("5 - 3 = {}", op(5, 3));  // 2
}
▶ Run

小结

  • 函数本身是一等公民,可以作为参数和返回值
  • 函数指针类型:fn(i32) -> i32
  • 高阶函数接受函数作为参数,提升代码复用性
  • 这些特性为闭包和迭代器奠定基础

练习题

详见:练习题