函数和控制流
本章深入介绍 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
}
📚 最佳实践
函数设计原则
- 单一职责 - 每个函数只做一件事
- 纯函数 - 尽量避免副作用
- 有意义的命名 - 函数名应该清楚表达功能
- 适当的长度 - 保持函数简洁
错误处理建议
- 使用 Result 和 Option - 避免 panic
- 提供有用的错误信息 - 帮助调试
- 及早返回 - 减少嵌套层级
- 文档化错误条件 - 说明可能的错误
性能考虑
- 避免不必要的复制 - 使用引用传递大对象
- 尾递归优化 - 编译器会优化尾递归
- 内联小函数 - 编译器会自动内联
- 批量操作 - 减少函数调用开销