请解释 Dart 中的元数据(Metadata)与注解的含义,并说明如何定义一个自定义注解?
考察说明
考察对 Dart 元数据与注解机制的理解及自定义注解的实现能力。
回答思路
- 【回答框架 1】元数据(Metadata)是附加在代码结构(如类、方法、变量、参数等)上的额外信息,用于描述代码的属性和行为。注解是元数据的一种具体形式,以 @ 符号开头,例如 @override。Dart 中的元数据主要供编译器和开发工具(如 analyzer)使用,也可在运行时通过反射(如 dart:mirrors,但 Web 平台可能不支持)获取。
- 【回答框架 2】自定义注解的本质是定义一个 const 构造函数。创建一个类,并将其构造函数声明为 const,则该类即可作为注解使用。例如:class MyAnnotation { final String info; const MyAnnotation(this.info); }。使用时在目标代码前加 @MyAnnotation('example')。注解可以应用于库、类、方法、属性、参数等位置。
- 【回答框架 3】为了在运行时读取注解信息,通常需要结合反射机制。Dart 提供 dart:mirrors 库(仅支持 VM),通过 MirrorSystem 获取类的注解列表。但注意 Flutter Web 或小程序等环境不支持 dart:mirrors,因此在实际开发中更多依赖代码生成(如 source_gen)在编译期解析注解。
- 【回答框架 4】注解的值必须是编译期常量,因此构造参数需要是 const 表达式。自定义注解可以包含字段,但字段必须是 final,并且构造函数必须为 const。同时,注解类本身不能是抽象的,且不能有非 const 构造函数。
- 【关键点 1】元数据是代码的附加描述信息,注解是其应用形式,以 @ 开头。
- 【关键点 2】自定义注解需创建具有 const 构造函数的类。
- 【关键点 3】注解值必须是编译期常量。
- 【关键点 4】运行时读取注解通常需要反射(dart:mirrors),但 Web 平台受限,常使用代码生成方案。
- 【易错点 1】容易混淆元数据和注解,实际注解是元数据的一种实现。
- 【易错点 2】误以为注解只能在运行时读取,忽略编译期处理(如代码生成)的常见用法。
- 【易错点 3】忘记注解参数必须为 const 常量,导致编译错误。