函数和控制流

本章深入介绍 Fleet 语言的函数定义、参数传递、返回值以及各种控制流结构。

📋 目录

🔧 函数基础

函数定义

Fleet 使用 fn 关键字定义函数:

fn function_name(parameter: type) -> return_type {
    // 函数体
    return value;
}

简单函数示例

// 无参数无返回值
fn say_hello() {
    print("Hello, Fleet!");
}

// 有参数无返回值
fn greet(name: str) {
    print("Hello, " + name + "!");
}

// 有参数有返回值
fn add(a: int, b: int) -> int {
    return a + b;
}

fn main() {
    say_hello();
    greet("World");
    let result = add(5, 3);
    print("Result: " + result);
}

函数重载

Fleet 支持基于参数类型的函数重载:

fn process(value: int) -> str {
    return "Integer: " + value;
}

fn process(value: str) -> str {
    return "String: " + value;
}

fn process(value: f64) -> str {
    return "Float: " + value;
}

fn main() {
    print(process(42));        // Integer: 42
    print(process("hello"));   // String: hello
    print(process(3.14));      // Float: 3.14
}

📥 参数和返回值

参数传递

按值传递(默认)

fn modify_value(mut x: int) {
    x = x + 10;  // 只修改局部副本
}

fn main() {
    let value = 5;
    modify_value(value);
    print(value);  // 输出: 5 (原值未改变)
}

引用传递

fn modify_reference(x: &mut int) {
    *x = *x + 10;  // 修改原值
}

fn main() {
    var value = 5;
    modify_reference(&mut value);
    print(value);  // 输出: 15 (原值被修改)
}

多返回值

fn divide_with_remainder(a: int, b: int) -> (int, int) {
    let quotient = a / b;
    let remainder = a % b;
    return (quotient, remainder);
}

fn main() {
    let (q, r) = divide_with_remainder(17, 5);
    print("17 ÷ 5 = " + q + " remainder " + r);
}

可选参数

fn greet_with_title(name: str, title: str = "Mr.") {
    print("Hello, " + title + " " + name);
}

fn main() {
    greet_with_title("Smith");           // Hello, Mr. Smith
    greet_with_title("Johnson", "Dr.");  // Hello, Dr. Johnson
}

可变参数

fn sum(numbers: ...int) -> int {
    var total = 0;
    loop num in numbers {
        total = total + num;
    }
    return total;
}

fn main() {
    print(sum(1, 2, 3));        // 6
    print(sum(1, 2, 3, 4, 5));  // 15
}

🔀 条件语句

if-else 语句

fn check_number(n: int) {
    if n > 0 {
        print("Positive");
    } else if n < 0 {
        print("Negative");
    } else {
        print("Zero");
    }
}

fn main() {
    check_number(5);   // Positive
    check_number(-3);  // Negative
    check_number(0);   // Zero
}

条件表达式

fn abs(n: int) -> int {
    return if n >= 0 { n } else { -n };
}

fn main() {
    print(abs(-5));  // 5
    print(abs(3));   // 3
}

复杂条件

fn classify_age(age: int) -> str {
    if age < 0 {
        return "Invalid age";
    } else if age < 13 {
        return "Child";
    } else if age < 20 {
        return "Teenager";
    } else if age < 60 {
        return "Adult";
    } else {
        return "Senior";
    }
}

fn main() {
    print(classify_age(10));  // Child
    print(classify_age(16));  // Teenager
    print(classify_age(30));  // Adult
}

🔄 循环结构

loop 循环(范围)

fn main() {
    // 基本范围循环
    loop i in 0..5 {
        print("Count: " + i);
    }

    // 包含结束值的范围
    loop i in 0..=5 {
        print("Count: " + i);  // 0 到 5(包含 5)
    }

    // 步长循环
    loop i in 0..10 step 2 {
        print("Even: " + i);  // 0, 2, 4, 6, 8
    }
}

集合迭代

fn main() {
    let numbers = [1, 2, 3, 4, 5];

    // 遍历数组
    loop num in numbers {
        print("Number: " + num);
    }

    // 带索引遍历
    loop (index, value) in numbers.enumerate() {
        print("Index " + index + ": " + value);
    }
}

映射迭代

fn main() {
    let scores = map{
        "Alice": 95,
        "Bob": 87,
        "Charlie": 92,
    };

    // 遍历键值对
    loop (name, score) in scores {
        print(name + ": " + score);
    }

    // 只遍历键
    loop name in scores.keys() {
        print("Student: " + name);
    }

    // 只遍历值
    loop score in scores.values() {
        print("Score: " + score);
    }
}

无限循环和控制

fn main() {
    var counter = 0;

    loop {
        counter = counter + 1;

        if counter == 3 {
            continue;  // 跳过当前迭代
        }

        if counter > 5 {
            break;     // 退出循环
        }

        print("Counter: " + counter);
    }
}

嵌套循环

fn print_multiplication_table() {
    loop i in 1..=10 {
        loop j in 1..=10 {
            print(i + " × " + j + " = " + (i * j));
        }
        print("---");
    }
}

fn main() {
    print_multiplication_table();
}

🎯 模式匹配

基本匹配

enum Color {
    Red,
    Green,
    Blue,
    RGB(int, int, int),
}

fn describe_color(color: Color) -> str {
    match color {
        Color::Red => return "It's red!",
        Color::Green => return "It's green!",
        Color::Blue => return "It's blue!",
        Color::RGB(r, g, b) => return "RGB(" + r + ", " + g + ", " + b + ")",
    }
}

fn main() {
    let red = Color::Red;
    let custom = Color::RGB(255, 128, 0);

    print(describe_color(red));     // It's red!
    print(describe_color(custom));  // RGB(255, 128, 0)
}

数值匹配

fn classify_number(n: int) -> str {
    match n {
        0 => return "Zero",
        1..=10 => return "Small",
        11..=100 => return "Medium",
        101..=1000 => return "Large",
        _ => return "Very large",
    }
}

fn main() {
    print(classify_number(0));    // Zero
    print(classify_number(5));    // Small
    print(classify_number(50));   // Medium
    print(classify_number(500));  // Large
    print(classify_number(5000)); // Very large
}

结构体匹配

struct Point {
    x: int,
    y: int,
}

fn analyze_point(p: Point) -> str {
    match p {
        Point { x: 0, y: 0 } => return "Origin",
        Point { x: 0, y } => return "On Y-axis at " + y,
        Point { x, y: 0 } => return "On X-axis at " + x,
        Point { x, y } if x == y => return "On diagonal",
        Point { x, y } => return "Point at (" + x + ", " + y + ")",
    }
}

fn main() {
    print(analyze_point(Point { x: 0, y: 0 }));  // Origin
    print(analyze_point(Point { x: 0, y: 5 }));  // On Y-axis at 5
    print(analyze_point(Point { x: 3, y: 3 }));  // On diagonal
}

守卫条件

fn categorize_age(age: int) -> str {
    match age {
        n if n < 0 => return "Invalid",
        n if n < 13 => return "Child",
        n if n < 20 => return "Teenager",
        n if n < 65 => return "Adult",
        _ => return "Senior",
    }
}

fn main() {
    print(categorize_age(10));  // Child
    print(categorize_age(25));  // Adult
    print(categorize_age(70));  // Senior
}

❌ 错误处理

Option 类型

fn safe_divide(a: int, b: int) -> Option {
    if b == 0 {
        return Option::None;
    } else {
        return Option::Some(a / b);
    }
}

fn main() {
    match safe_divide(10, 2) {
        Option::Some(result) => print("Result: " + result),
        Option::None => print("Cannot divide by zero"),
    }

    match safe_divide(10, 0) {
        Option::Some(result) => print("Result: " + result),
        Option::None => print("Cannot divide by zero"),
    }
}

Result 类型

enum MathError {
    DivisionByZero,
    Overflow,
}

fn checked_divide(a: int, b: int) -> Result {
    if b == 0 {
        return Result::Err(MathError::DivisionByZero);
    }

    let result = a / b;
    if result > 1000000 {
        return Result::Err(MathError::Overflow);
    }

    return Result::Ok(result);
}

fn main() {
    match checked_divide(10, 2) {
        Result::Ok(value) => print("Success: " + value),
        Result::Err(MathError::DivisionByZero) => print("Error: Division by zero"),
        Result::Err(MathError::Overflow) => print("Error: Result too large"),
    }
}

错误传播

fn parse_and_divide(a_str: str, b_str: str) -> Result {
    let a = parse_int(a_str)?;  // ? 操作符自动传播错误
    let b = parse_int(b_str)?;

    if b == 0 {
        return Result::Err("Division by zero");
    }

    return Result::Ok(a / b);
}

fn main() {
    match parse_and_divide("10", "2") {
        Result::Ok(result) => print("Result: " + result),
        Result::Err(error) => print("Error: " + error),
    }
}

🎯 高级函数特性

高阶函数

fn apply_operation(a: int, b: int, op: fn(int, int) -> int) -> int {
    return op(a, b);
}

fn add(x: int, y: int) -> int {
    return x + y;
}

fn multiply(x: int, y: int) -> int {
    return x * y;
}

fn main() {
    print(apply_operation(5, 3, add));      // 8
    print(apply_operation(5, 3, multiply)); // 15
}

闭包

fn create_adder(n: int) -> fn(int) -> int {
    return |x| x + n;  // 闭包捕获变量 n
}

fn main() {
    let add_five = create_adder(5);
    print(add_five(10));  // 15

    let add_ten = create_adder(10);
    print(add_ten(10));   // 20
}

📚 最佳实践

函数设计原则

  1. 单一职责 - 每个函数只做一件事
  2. 纯函数 - 尽量避免副作用
  3. 有意义的命名 - 函数名应该清楚表达功能
  4. 适当的长度 - 保持函数简洁

错误处理建议

  1. 使用 Result 和 Option - 避免 panic
  2. 提供有用的错误信息 - 帮助调试
  3. 及早返回 - 减少嵌套层级
  4. 文档化错误条件 - 说明可能的错误

性能考虑

  1. 避免不必要的复制 - 使用引用传递大对象
  2. 尾递归优化 - 编译器会优化尾递归
  3. 内联小函数 - 编译器会自动内联
  4. 批量操作 - 减少函数调用开销

🔗 相关主题