Dart如何获取包的变量、函数等列表?实现类似Python dir的功能
Dart 实现类似 Python
dir() 枚举成员功能的方案 为什么尝试用 try-catch 会触发编译期崩溃
Dart 是静态强类型语言,在代码中直接编写print(student.obj)这类静态访问成员的逻辑时,编译器会在构建阶段做严格的成员存在性校验。只要对应类上不存在obj这个getter,会直接抛出你遇到的这类编译错误——这类错误发生在代码编译阶段,根本不会进入运行时执行流程,而try-catch块是运行时的异常捕获机制,完全覆盖不到编译阶段的校验逻辑,自然无法捕获报错。
核心实现方案
要实现类似Python中dir()的功能——运行时枚举类、实例、导入库的全部成员,动态检查成员是否存在,需要借助Dart提供的反射能力,完全绕开编译期的静态成员校验流程:
- 首先引入反射核心库:
import 'dart:mirrors'; - 枚举类/实例的全部成员,等价于Python的
dir(对象)输出:- 对目标对象创建镜像实例,拿到类的元数据信息
- 读取类上声明的所有成员(包含变量、方法、构造器等)
- 匹配目标成员名是否存在,只有确认存在的前提下,再动态读取对应成员的值
对应示例代码:
// 拿到student实例的镜像对象 InstanceMirror studentMirror = reflect(student); // 拿到student所属类的元信息 ClassMirror studentClassMirror = studentMirror.type; // 枚举类上的全部声明成员,等价于Python dir(student)的返回值 List<Symbol> classAllMembers = studentClassMirror.declarations.keys.toList(); // 检查是否存在指定的obj成员 bool isObjExist = classAllMembers.contains(const Symbol('obj')); // 动态读取成员,不会触发编译期报错 if (isObjExist) { print(studentMirror.getField(const Symbol('obj')).reflectee); } - 如果需要检查导入包的顶层变量、顶层函数,可以通过
currentMirrorSystem().libraries拿到所有已加载库的镜像,枚举对应库下的全部顶层声明成员即可。
注意事项
dart:mirrors反射能力仅在纯Dart VM环境(命令行脚本、服务端程序)下可以完整使用,在Flutter的Release构建模式下,反射代码会被Tree Shaking裁剪,导致运行时拿不到完整的成员信息- 如果不需要动态运行时枚举,只是校验自己开发的包内成员是否存在,可以借助代码生成工具在编译期生成固定的成员清单,替代反射能力。
内容的提问来源于stack exchange,提问作者Ali Tlekbai
相关产品推荐
相关产品推荐

