Dart中的符号(Symbol)是不透明的动态字符串名称,用于反映库中的元数据。简而言之,符号是一种存储人类可读字符串与优化供计算机使用的字符串之间关系的方法。
反射是一种在运行时获取类型元数据的机制,如类中的方法数,它具有的构造函数数或函数中的参数数。甚至可以调用在运行时加载的类型的方法。
在Dart反射中,dart:mirrors
包中提供了特定的类。此库适用于Web应用程序和命令行应用程序。
语法
Symbol obj = new Symbol('name'); // expects a name of class or function or library to reflect
name
必须是有效的公共Dart成员名称,公共构造函数名称或库名称。
示例
请考虑以下示例。代码在库foo_lib
中声明了一个类Foo
。该类定义方法:m1
,m2
和m3
。
文件:Foo.dart -
library foo_lib; // libarary name can be a symbol class Foo { // class name can be a symbol m1() { // method name can be a symbol print("Inside m1"); } m2() { print("Inside m2"); } m3() { print("Inside m3"); } }
以下代码在Symbol
类型的帮助下加载Foo.dart
库并搜索Foo
类。由于需要反射上述库中的元数据,因此这里需要代码导入dart:mirrors
库。
文件:FooSymbol.dart
import 'dart:core'; import 'dart:mirrors'; import 'Foo.dart'; main() { Symbol lib = new Symbol("foo_lib"); //library name stored as Symbol Symbol clsToSearch = new Symbol("Foo"); // class name stored as Symbol if(checkIf_classAvailableInlibrary(lib, clsToSearch)) // searches Foo class in foo_lib library print("class found.."); } bool checkIf_classAvailableInlibrary(Symbol libraryName, Symbol className) { MirrorSystem mirrorSystem = currentMirrorSystem(); LibraryMirror libMirror = mirrorSystem.findLibrary(libraryName); if (libMirror != null) { print("Found Library"); print("checkng...class details.."); print("No of classes found is : ${libMirror.declarations.length}"); libMirror.declarations.forEach((s, d) => print(s)); if (libMirror.declarations.containsKey(className)) return true; return false; } }
注意:代码行 - libMirror.declarations.forEach((s, d) => print(s));
将在运行时迭代库中的每个声明,并将声明打印为Symbol
的类型。
此代码应产生以下输出 -
Found Library checkng...class details.. No of classes found is : 1 Symbol("Foo") // class name displayed as symbol class found.
示例:显示类的实例方法数
下面来看看如何显示在类实例方法的数量。可通过使用ClassMirror
预定义类来实现。
import 'dart:core'; import 'dart:mirrors'; import 'Foo.dart'; main() { Symbol lib = new Symbol("foo_lib"); Symbol clsToSearch = new Symbol("Foo"); reflect_InstanceMethods(lib, clsToSearch); } void reflect_InstanceMethods(Symbol libraryName, Symbol className) { MirrorSystem mirrorSystem = currentMirrorSystem(); LibraryMirror libMirror = mirrorSystem.findLibrary(libraryName); if (libMirror != null) { print("Found Library"); print("checkng...class details.."); print("No of classes found is : ${libMirror.declarations.length}"); libMirror.declarations.forEach((s, d) => print(s)); if (libMirror.declarations.containsKey(className)) print("found class"); ClassMirror classMirror = libMirror.declarations[className]; print("No of instance methods found is ${classMirror.instanceMembers.length}"); classMirror.instanceMembers.forEach((s, v) => print(s)); } }
此代码应产生以下输出 -
Found Library checkng...class details.. No of classes found is : 1 Symbol("Foo") found class No of instance methods found is 8 Symbol("==") Symbol("hashCode") Symbol("toString") Symbol("noSuchMethod") Symbol("runtimeType") Symbol("m1") Symbol("m2") Symbol("m3")
将Symbol转换为字符串
可以使用MirrorSystem
类将存储在符号中的类或类的名称转换回字符串。以下代码显示如何将符号转换为字符串。
import 'dart:mirrors'; void main(){ Symbol lib = new Symbol("foo_lib"); String name_of_lib = MirrorSystem.getName(lib); print(lib); print(name_of_lib); }
执行上面示例代码,得到以下结果 -
Symbol("foo_lib") foo_lib