Skip to content

函数

函数是执行特定任务的可重用代码块。在 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
}

最佳实践

  1. 对简单的单行函数使用箭头语法
  2. 对具有多个参数的函数优先使用命名参数
  3. 对强制性命名参数使用 required
  4. 保持函数小巧并专注于单一任务
  5. 使用描述性名称来指示函数的作用
  6. 为复杂函数添加注释文档

完整示例

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)}');
}

下一步