如何在 Dart 中扩展函数?

Posted

技术标签:

【中文标题】如何在 Dart 中扩展函数?【英文标题】:How can I extend functions in Dart? 【发布时间】:2020-02-06 06:06:03 【问题描述】:

我知道the extension feature in Dart,但是如何将它与函数一起使用?

基本上,我面临两个问题:

    on (extension FancyFunction on ?) 我应该扩展什么? 我想添加一个像toAsync 这样的函数,使函数返回其通常结果的Future

    如何实现调用? 我可以创建一个执行this()this.call()callAsync 成员,但我想使用常规调用语法,即只使用括号。

【问题讨论】:

【参考方案1】:

在扩展函数时我要扩展什么?

Dart 有一个Function type。这可以扩展,您可以根据需要传递类型参数。 这是example from the changelog:

extension CurryFunction<R, S, T> on R Function(S, T)  ... 

此外,您可以扩展函数的任何typedef

要添加toAsynccallAsync 功能,可以使用通用返回类型R。请注意,这只会扩展不带参数的函数,因为 Function() 不带参数:

extension FancyFunction<R> on R Function() 
  Future<R> Function() toAsync() => () async => this();

现在,可以这样使用:

void syncHello() => print('Hello');

void main() 
  final asyncHello = syncHello.toAsync();

  asyncHello().then((_) => print(', World!'));

如何实现调用?

Dart 中的每个类都可以implement the call method。您可以简单地使用 括号.call() 来执行此方法。 这是一个示例实现:

extension FancyFunction<R> on R Function() 
  Future<R> call() async => this();

由于每个Function 已经实现call,扩展成员不能隐式调用。 相反,您必须明确将您的函数声明为 FancyFunction 才能调用它:

void syncHello() => print('Hello');

void main() 
  FancyFunction(syncHello)()
      .then((_) => print(', World!'));

请注意,FancyFunction(syncHello)()FancyFunction(syncHello).call() 的方法调用相同。

但是,现在我们有两个问题:

我们必须明确声明我们的函数是FancyFunction,这在某种程度上违背了扩展的目的。

call 方法将始终返回 Future,因为当我们声明 FancyFunction 时,无法再访问常规调用方法。

相反,添加像callAsync 这样的方法似乎是一个更好的解决方案:

extension FancyFunction<R> on R Function() 
  Future<R> callAsync() async => this();

现在,callAsync 可以再次隐式使用:

void syncHello() => print('Hello');

void main() 
  syncHello.callAsync()
      .then((_) => print(', World!'));

  syncHello(); // regular call

【讨论】:

以上是关于如何在 Dart 中扩展函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Flutter中读取音频扩展并在ListView中显示?

Flutter枚举

dart系列之:集合使用最佳实践

如何在 Dart 中仅使用级联或链式调用干净地映射/排序/折叠/排序/扩展?

如何从 html 按钮调用 Firefox 扩展中的函数

如何从 PHP 扩展中重载函数?