Flutter---函数

怎么理解Flutter中的函数?Dart是一门面向对象的编程语言,所以函数也是对象,而函数属于Function类型,所以Dart可以把函数当成变量传给另外一个函数,也可以把Dart类的实例当作方法来调用。

一.函数赋值给变量

在 Dart 中,你可以将一个函数直接赋值给一个变量,这个变量的类型就是 Function。之后,你可以通过这个变量来调用函数。

Dart 复制代码
// 1. 定义一个普通的函数
String greet(String name) {
  return 'Hello, $name!';
}

void main() {
  // 2. 将函数 greet 赋值给变量 myFunction
  // 注意:这里是 greet,不是 greet(),我们赋值的是函数本身,而不是调用它的结果
  Function myFunction = greet; 

  // 3. 通过变量调用函数
  print(myFunction('Alice')); // 输出:Hello, Alice!
  print(myFunction('Bob'));   // 输出:Hello, Bob!
}

在这个例子中,myFunction变量就成为了 greet函数的一个引用,你可以像使用原函数一样使用它。

二.函数作为参数传递

这是函数式编程的一个核心概念,非常强大。你可以把一个函数(通常称为回调函数)作为参数传递给另一个函数,让后者在适当的时机(比如完成某项任务后、或者某个事件发生时)来调用你传入的函数。

Dart 复制代码
// 1. 定义一个函数,它接受一个字符串和一个函数作为参数
// 第二个参数 `action` 是一个 Function 类型,它自己接受一个 String 参数并不返回内容(void)
void processString(String message, Function(String) action) {
  // 在 processString 函数内部,调用传入的 action 函数
  action(message.toUpperCase()); // 例如,将消息转为大写后处理
}

void main() {
  // 2. 定义一个匹配 `Function(String)` 签名的函数,比如一个简单的打印函数
  void myPrint(String text) {
    print('打印结果: $text');
  }

  // 3. 调用 processString,并将 myPrint 函数作为参数传入
  processString('This is a message', myPrint); 
  // 最终输出:打印结果: THIS IS A MESSAGE,又大写又打印

  // 4. 更常见的做法:直接传入一个匿名函数(或箭头函数)
  processString('Another message', (text) {
    print('匿名函数处理: $text');
  });
  // 输出:匿名函数处理: ANOTHER MESSAGE

  // 使用箭头函数简写
  processString('Last message', (text) => print('箭头函数: $text'));
  // 输出:箭头函数: LAST MESSAGE
}

这种模式在 Flutter 中极其常见,例如按钮的 onPressed参数就是接受一个回调函数,用来定义按钮被点击时的行为。

三.函数作为返回值

一个函数可以返回另一个函数。返回的函数通常形成了一个"闭包",意味着它可以记住并访问创建它的词法作用域中的变量,即使函数在其原始作用域之外被调用。

Dart 复制代码
// 1. 定义一个函数,它返回一个 Function
// 返回的函数类型是:int Function(int) (接受一个int参数,返回一个int)
Function makeAdder(int addBy) {
  // 2. 在 makeAdder 内部定义并返回一个匿名函数
  int adder(int number) {
    return addBy + number;
  }
  return adder; // 返回这个函数,注意不是调用它
}

void main() {
  // 3. 调用 makeAdder 来"制造"特定的加法函数
  var addTwo = makeAdder(2);   // 得到一个"加2"的函数
  var addTen = makeAdder(10);  // 得到一个"加10"的函数

  // 4. 使用这些被返回的函数
  print(addTwo(3));   // 输出:5 (3 + 2)
  print(addTen(3));   // 输出:13 (3 + 10)
  print(addTwo(10));  // 输出:12 (10 + 2)
}

这里,addTwoaddTen就是被"制造"出来的新函数。它们"记住"了创建时传入的 addBy值(分别是2和10)。

四.类的实例作为方法调用

通过在一个类中实现 call()方法,你可以让这个类的实例像函数一样被调用。这为你的对象提供了类似函数的行为。

Dart 复制代码
// 1. 定义一个类,并实现 call 方法
class Greeter {
  final String greeting;

  Greeter(this.greeting); // 构造函数

  // 2. 实现 call 方法。当实例被"调用"时,这个方法会被执行
  String call(String name) {
    return '$greeting, $name!';
  }
}

void main() {
  // 3. 创建类的实例
  var formalGreeter = Greeter('Hello');
  var casualGreeter = Greeter('Hi there');

  // 4. 像调用函数一样调用这些实例!
  print(formalGreeter('Alice'));    // 输出:Hello, Alice!
  print(casualGreeter('Bob'));       // 输出:Hi there, Bob!

  // 当然,你仍然可以像普通对象一样使用它们
  print(formalGreeter.greeting);     // 输出:Hello
}

这种方式让你的对象在具备数据和状态(类的普通属性)的同时,也拥有了可执行的行为(call方法),非常灵活。

相关推荐
恋猫de小郭1 小时前
Android 禁止侧载将正式实施,需要等待 24 小时冷静期
android·flutter·harmonyos
FFF-X1 小时前
解决 Flutter Gradle 下载报错:修改默认 distributionUrl
flutter
程序员Ctrl喵21 小时前
异步编程:Event Loop 与 Isolate 的深层博弈
开发语言·flutter
前端不太难1 天前
Flutter 如何设计可长期维护的模块边界?
flutter
小蜜蜂嗡嗡1 天前
flutter列表中实现置顶动画
flutter
始持1 天前
第十二讲 风格与主题统一
前端·flutter
始持1 天前
第十一讲 界面导航与路由管理
flutter·vibecoding
始持1 天前
第十三讲 异步操作与异步构建
前端·flutter
新镜1 天前
【Flutter】 视频视频源横向、竖向问题
flutter
黄林晴1 天前
Compose Multiplatform 1.10 发布:统一 Preview、Navigation 3、Hot Reload 三箭齐发
android·flutter