dart:函数和类的call方法

函数的call方法

在 Dart 中,所有函数对象都自带一个 .call 方法,它和直接调用函数是等价的。

void add(int a, int b) {
  print("sum = ${a + b}");
}

void main() {
  var f = add;

  // 普通调用
  f(2, 3);       // sum = 5

  // 使用 .call 调用
  f.call(4, 5);  // sum = 9

  // .call 和直接调用完全一样
  assert(f(10, 20) == f.call(10, 20));
}

类的Call方法–Callable 类

在 Dart 里,如果一个类实现了 call() 方法,那么它的实例可以像函数一样被调用,这种类叫 callable class可调用类)。

class Adder {
  int call(int a, int b) => a + b;
}

void main() {
  var add = Adder();
  
  print(add(3, 4)); // 7,像函数一样调用
}

特点

  • call() 方法可以有任意参数和返回值
  • 调用时不需要写 add.call(3, 4),直接 add(3, 4) 就行
  • 常用于:
    • 封装函数逻辑
    • Flutter 中 widget builder
    • 高阶函数替代方案

示例:带状态的 Callable

class Multiplier {
  int factor;
  Multiplier(this.factor);

  int call(int value) => value * factor;
}

void main() {
  var triple = Multiplier(3);
  print(triple(5)); // 15
}

这里 triple 是一个对象,但用起来像函数,而且它记住了 factor

为什么需要Call方法

函数对象为什么需要 .call

对于 函数对象 来说,().call() 的效果完全一样。那么为什么 Dart 里还要多此一举?

答案是:为了统一设计,让函数和普通对象都能通过 .call() 被调用。

也就是说,.call 是 Dart 提供的一种语法约定,它让「函数」和「类实例」在调用方式上保持一致。

类对象为什么需要 .call

在 Dart 中,任何类都可以实现一个 call 方法,这样它的实例就能像函数一样使用:

class Multiplier {
  final int factor;
  Multiplier(this.factor);

  int call(int x) => x * factor;
}

void main() {
  var triple = Multiplier(3);

  print(triple(5));      // 15 (像函数一样调用)
  print(triple.call(5)); // 15 (显式调用)
}

什么时候必须用 .call 而不能直接用 ()

变量名和函数名冲突

void greet() => print("Hello!");

void main() {
  var greet = greet; // 这里变量名和函数名冲突了

  // greet(); ❌ 这会报错:
  // Error: The method 'greet' isn't defined for the class '...'

  // ✅ 解决办法:用 .call 调用
  greet.call(); // 输出:Hello!
}

这里 greet 被重新赋值成了一个函数对象,

如果直接写 greet(),编译器会认为你是要调用 变量的 getter 方法,结果报错。

但是 .call() 明确告诉 Dart:我要执行这个函数对象。

统一“函数”和“可调用对象”

class Doubler {
  int call(int x) => x * 2;
}

void run(Function f) {
  // 不管 f 是函数还是对象,都可以用 .call 调用
  print(f.call(5));
}

void main() {
  int times3(int x) => x * 3;

  run(times3);     // 输出 15
  run(Doubler());  // 输出 10
}

这里 run 函数里用 .call,就能同时支持 普通函数实现了 call 方法的对象

如果只写 f(5),那对于 Doubler 这种对象就会报错。

×

喜欢就点赞,疼爱就打赏