如何在Dart中使用类型别名/Typedefs(也是非函数)



我很早就知道Dart中的函数typedefs。在回答这个问题时也对它们进行了解释。

现在,我听说Dart中出现了非函数类型别名(或非函数类型定义(。


我想知道两件事:

  • Dart中的(非函数(typedefs究竟是什么
  • 我如何使用它们(在我的Flutter项目中(

Dart中的广义类型别名/typedefs您可以查看完整设计文档的通用类型aliases的功能规范。

在此之前,我想指出Dart过去只支持函数的typedefs新的广义功能支持任何类型的typedef

typedef JsonMap = Map<String, dynamic>;
JsonMap parseJsonMap(String input) => json.decode(input) as JsonMap;

当您有多个泛型类型(类型参数(,导致键入冗长的类型名称时,这一点尤其有用,例如Map<ScaffoldFeatureController<SnackBar, SnackBarClosedReason>, SnackBar>。现在可以使用类型别名简化:

typedef ScaffoldSnackBarMap = Map<ScaffoldFeatureController<SnackBar, SnackBarClosedReason>, SnackBar>;

语法

如果从上面的例子中看不清楚,这是typealiases/typedefs:的语法

'typedef' identifier typeParameters? '=' type ';'

这意味着您始终需要以typedef关键字开头,然后再加上所需的标识符,例如FooTypeDef。之后,您可以添加类型参数,例如Foo<K, V>。最后一步是添加=符号,然后添加要为其创建别名的实际类型。这可以是任何类型,即类、基元类型、函数类型或w/e。不要忘记最后的;;(

// Type parameters / generic types in typedef.
typedef Foo<K, V> = Map<K, V>;
// Type alias for regular types.
typedef Bar = Widget;
// As well as primitive types.
typedef Baz = int;
// Function types are also supported.
typedef FooFunction<T, R> = R Function(T param);

弃用名称

此外,您可以将typedefs用于任何类名称。假设您想将类从Provider重命名为Pod,因为您认为前者过于冗长。如果您正在维护一个包,这将是一个突破性的更改。使用新的通用类型别名,您可以简单地重命名类并创建一个您不赞成的类型别名:

class NewClassName<T> {}
@Deprecated("Use NewClassName instead")
typedef OldClassName<T> = NewClassName<T>;

请注意,此示例和上面的示例取自该功能的CHANGELOG条目。

如何使用它们

默认情况下,该功能将与Dart 2.13一起发布,但目前仍处于试验阶段。我将介绍如何以两种方式使用它;实验方法可以稍后删除。

飞镖2.13

正如我之前提到的,该功能将在默认情况下启用从Dart 2.13开始。如果您当前已经安装了Dart 2.13(例如,您可以使用dart --version进行检查(,则可以使用此方法。否则,您应该参考下面的实验支持部分。

pubspec.yaml中,您需要将Dart SDK约束上的下界定义为大于或等于2.13.0:

environment:
dart: '>=2.13.0 <3.0.0'

实验支持

在Flutter项目(或任何其他Dart项目(中,您当前需要将其作为实验启用。这意味着它们隐藏在功能标志后面。


可以使用analysis_options.yaml配置实验飞镖功能。您可以简单地在项目目录的根目录中创建一个analysis_options.yaml文件,并添加以下行:

analyzer:
enable-experiment:
- nonfunction-type-aliases

现在,您还需要在运行(或构建(应用程序时启用实验:

flutter run --enable-experiment=nonfunction-type-aliases

要确保您可以使用此功能,请使用master通道(使用Flutter时为flutter channel master(。

最新更新