函数
函数是 MiraScript 中组织和复用代码的基本方式。
声明函数
使用 fn 关键字 声明函数。函数体是一个块表达式,最后一个表达式的值就是函数的返回值:
fn greet(name) {
"你好,$name!"
}
debug_print(greet("小明"));
debug_print(greet("小红")); 多参数函数
fn add(x, y) {
x + y
}
fn distance(x1, y1, x2, y2) {
sqrt((x2 - x1)^2 + (y2 - y1)^2)
}
debug_print("3 + 4 =", add(3, 4));
debug_print("距离:", distance(0, 0, 3, 4)); 单参数简写
当函数只有一个参数时,可以省略参数列表,该参数自动命名为 it:
fn double { it * 2 }
fn square { it^2 }
fn is_even { it % 2 == 0 }
debug_print("double(5) =", double(5));
debug_print("square(4) =", square(4));
debug_print("is_even(6) =", is_even(6)); 提示
it 是 MiraScript 中非常实用的特性,在与 map、filter 等函数配合时尤其简洁。
函数表达式
函数也可以作为值赋给变量。这种写法称为函数表达式或匿名函数:
let multiply = fn (x, y) { x * y };
let cube = fn { it^3 };
debug_print("3 × 4 =", multiply(3, 4));
debug_print("3³ =", cube(3)); 函数声明 vs 函数表达式
函数声明 fn name(...) 会被提升,可以在声明之前调用。函数表达式没有这个特性:
// 函数声明可以在定义之前调用
debug_print(say_hello());
fn say_hello() { "Hello!" } return 语句
函数体中最后一个表达式的值会自动作为返回值。也可以使用 return 提前返回:
fn classify(n) {
if n > 0 {
return "正数";
}
if n < 0 {
return "负数";
}
"零" // 最后一个表达式,自动返回
}
debug_print(classify(5));
debug_print(classify(-3));
debug_print(classify(0)); 高阶函数
函数可以作为参数传递给其他函数,也可以作为返回值。这种使用方式称为高阶函数:
函数作为参数
fn apply_twice(func, value) {
func(func(value))
}
fn add_one { it + 1 }
fn double { it * 2 }
debug_print("add_one 两次:", apply_twice(add_one, 5)); // 7
debug_print("double 两次:", apply_twice(double, 3)); // 12 与 map、filter 配合
匿名函数 + it 让数据处理代码非常简洁:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8];
// 过滤偶数,然后翻倍
let result = filter(numbers, fn { it % 2 == 0 });
let doubled = map(result, fn { it * 2 });
debug_print("结果:", doubled); 展开参数
收集参数
使用 .. 将多余的参数收集为数组:
fn print_all(first, ..rest) {
debug_print("第一个:", first);
debug_print("其余:", rest);
}
print_all("a", "b", "c", "d"); 展开数组为参数
调用函数时,用 .. 将数组展开为多个参数:
fn add(x, y) { x + y }
let pair = [3, 4];
debug_print("展开调用:", add(..pair)); // 等价于 add(3, 4) 默认参数值
MiraScript 没有专门的默认参数语法,但可以用 ?? 空合并运算符实现:
fn greet(name, greeting) {
let g = greeting ?? "你好";
"$g,$name!"
}
debug_print(greet("小明", "早上好"));
debug_print(greet("小红")); // greeting 为 nil,使用默认值 闭包
函数可以捕获外层作用域中的变量,这称为闭包:
fn create_counter(start) {
let mut count = start;
return fn () {
count += 1;
count
};
}
let counter = create_counter(0);
debug_print(counter()); // 1
debug_print(counter()); // 2
debug_print(counter()); // 3
// 每个计数器是独立的
let another = create_counter(100);
debug_print(another()); // 101
debug_print(counter()); // 4,不受影响 函数工厂
利用闭包可以创建"定制"的函数:
fn create_multiplier(factor) {
return fn { it * factor };
}
let times3 = create_multiplier(3);
let times5 = create_multiplier(5);
debug_print("times3(4) =", times3(4)); // 12
debug_print("times5(4) =", times5(4)); // 20 递归
函数可以调用自身,称为递归:
fn factorial(n) {
if n <= 1 { 1 }
else { n * factorial(n - 1) }
}
debug_print("5! =", factorial(5)); // 120
debug_print("10! =", factorial(10)); // 3628800 实际应用
// 使用高阶函数进行数据处理
let students = [
(name: "小明", score: 85),
(name: "小红", score: 92),
(name: "小华", score: 78),
(name: "小李", score: 95),
(name: "小张", score: 60),
];
// 找出优秀学生(90分以上)的名字
let excellent = filter(students, fn { it.score >= 90 });
let names = map(excellent, fn { it.name });
debug_print("优秀学生:", names);
// 计算平均分
let total = map(students, fn { it.score });
let avg = sum(..total) / len(total);
debug_print("平均分: $(avg:.1)"); 小结
fn name(params) { body }声明函数,最后一个表达式是返回值- 单参数函数可省略参数列表,参数名为
it - 函数可以作为值传递(高阶函数)
..用于收集和展开参数- 闭包可以捕获外层变量
- 函数可以递归调用自身