函数
函数是执行特定任务的可重用代码块。在 Dart 中,函数是一等对象,这意味着它们可以赋值给变量、作为参数传递以及从其他函数返回。
基本函数语法
dart
// 带返回类型的函数
int add(int a, int b) {
return a + b;
}
// 无返回值的函数
void greet(String name) {
print('你好,$name!');
}
// 箭头函数(单表达式)
int multiply(int a, int b) => a * b;
void main() {
print(add(5, 3)); // 8
greet('Alice'); // 你好,Alice!
print(multiply(4, 5)); // 20
}参数
必需位置参数
dart
String fullName(String first, String last) {
return '$first $last';
}
print(fullName('张', '三')); // 张 三可选位置参数
使用方括号 []:
dart
String greet(String name, [String? title]) {
if (title != null) {
return '你好,$title $name';
}
return '你好,$name';
}
print(greet('Alice')); // 你好,Alice
print(greet('Bob', '博士')); // 你好,博士 Bob命名参数
使用花括号 {}:
dart
void printInfo({String? name, int? age}) {
print('姓名:$name,年龄:$age');
}
printInfo(name: 'Alice', age: 25);
printInfo(age: 30, name: 'Bob'); // 顺序无关紧要必需命名参数
dart
void createUser({required String name, required String email}) {
print('用户:$name,邮箱:$email');
}
createUser(name: 'Alice', email: 'alice@example.com');
// createUser(name: 'Bob'); // 错误:email 是必需的默认参数值
dart
String greet(String name, [String greeting = '你好']) {
return '$greeting,$name!';
}
print(greet('Alice')); // 你好,Alice!
print(greet('Bob', '嗨')); // 嗨,Bob!
// 带默认值的命名参数
void printMessage({String message = '默认', int times = 1}) {
for (int i = 0; i < times; i++) {
print(message);
}
}
printMessage(); // 默认(一次)
printMessage(message: '嗨', times: 3); // 嗨(三次)返回值
dart
// 显式返回
int square(int n) {
return n * n;
}
// 箭头函数
int cube(int n) => n * n * n;
// 使用记录返回多个值(Dart 3.0+)
(int, int) minMax(List<int> numbers) {
return (numbers.reduce((a, b) => a < b ? a : b),
numbers.reduce((a, b) => a > b ? a : b));
}
void main() {
var (min, max) = minMax([3, 1, 4, 1, 5, 9]);
print('最小值:$min,最大值:$max'); // 最小值:1,最大值:9
}匿名函数(Lambda)
dart
// 匿名函数
var multiply = (int a, int b) {
return a * b;
};
// 箭头函数
var add = (int a, int b) => a + b;
// 与集合一起使用
List<int> numbers = [1, 2, 3, 4, 5];
numbers.forEach((num) {
print(num * 2);
});
var doubled = numbers.map((num) => num * 2).toList();
print(doubled); // [2, 4, 6, 8, 10]高阶函数
接受其他函数作为参数或返回函数的函数:
dart
// 函数作为参数
void executeOperation(int a, int b, int Function(int, int) operation) {
print('结果:${operation(a, b)}');
}
int add(int a, int b) => a + b;
int multiply(int a, int b) => a * b;
void main() {
executeOperation(5, 3, add); // 结果:8
executeOperation(5, 3, multiply); // 结果:15
// 使用匿名函数
executeOperation(5, 3, (a, b) => a - b); // 结果:2
}
// 返回函数的函数
Function makeMultiplier(int factor) {
return (int value) => value * factor;
}
void main() {
var double = makeMultiplier(2);
var triple = makeMultiplier(3);
print(double(5)); // 10
print(triple(5)); // 15
}闭包
从周围作用域捕获变量的函数:
dart
Function makeCounter() {
int count = 0;
return () {
count++;
return count;
};
}
void main() {
var counter = makeCounter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3
}递归函数
dart
// 阶乘
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
// 斐波那契
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
void main() {
print(factorial(5)); // 120
print(fibonacci(7)); // 13
}生成器函数
同步生成器
返回 Iterable:
dart
Iterable<int> countTo(int max) sync* {
for (int i = 1; i <= max; i++) {
yield i;
}
}
void main() {
for (var num in countTo(5)) {
print(num); // 1, 2, 3, 4, 5
}
}异步生成器
返回 Stream:
dart
Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
void main() async {
await for (var num in countStream(3)) {
print(num); // 1(1秒后),2(2秒后),3(3秒后)
}
}函数类型
dart
// 类型定义
typedef MathOperation = int Function(int, int);
int add(int a, int b) => a + b;
int subtract(int a, int b) => a - b;
void calculate(int x, int y, MathOperation operation) {
print(operation(x, y));
}
void main() {
calculate(10, 5, add); // 15
calculate(10, 5, subtract); // 5
}最佳实践
- 对简单的单行函数使用箭头语法
- 对具有多个参数的函数优先使用命名参数
- 对强制性命名参数使用 required
- 保持函数小巧并专注于单一任务
- 使用描述性名称来指示函数的作用
- 为复杂函数添加注释文档
完整示例
dart
// 具有各种函数类型的计算器
typedef Operation = double Function(double, double);
// 基本操作
double add(double a, double b) => a + b;
double subtract(double a, double b) => a - b;
double multiply(double a, double b) => a * b;
double divide(double a, double b) => b != 0 ? a / b : 0;
// 高阶函数
void performCalculation({
required double x,
required double y,
required Operation operation,
String? label,
}) {
double result = operation(x, y);
String operationName = label ?? '操作';
print('$operationName:$x 和 $y = $result');
}
// 返回函数的函数
Operation getOperation(String type) {
return switch (type) {
'add' => add,
'subtract' => subtract,
'multiply' => multiply,
'divide' => divide,
_ => (a, b) => 0,
};
}
void main() {
double a = 10, b = 5;
performCalculation(x: a, y: b, operation: add, label: '加法');
performCalculation(x: a, y: b, operation: subtract, label: '减法');
performCalculation(x: a, y: b, operation: multiply, label: '乘法');
performCalculation(x: a, y: b, operation: divide, label: '除法');
// 使用函数工厂
var op = getOperation('multiply');
print('动态操作:${op(a, b)}');
}