Символы в Dart — это непрозрачное динамическое имя строки, используемое для отражения метаданных из библиотеки. Проще говоря, символы — это способ хранения отношений между читаемой человеком строкой и строкой, оптимизированной для использования компьютерами.
Reflection — это механизм для получения метаданных типа во время выполнения, таких как количество методов в классе, количество конструкторов или количество параметров в функции. Вы даже можете вызвать метод типа, который загружается во время выполнения.
В Dart Reflection определенные классы доступны в пакете dart: mirrors . Эта библиотека работает как в веб-приложениях, так и в приложениях командной строки.
Синтаксис
Symbol obj = new Symbol('name'); // expects a name of class or function or library to reflect
Имя должно быть действительным общедоступным именем члена Dart, общедоступным именем конструктора или библиотекым именем.
пример
Рассмотрим следующий пример. Код объявляет класс Foo в библиотеке foo_lib . Класс определяет методы 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"); } }
Следующий код загружает библиотеку Foo.dart и ищет класс Foo с помощью типа Symbol. Поскольку мы отражаем метаданные из вышеуказанной библиотеки, код импортирует библиотеку 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")
Преобразовать символ в строку
Вы можете преобразовать имя типа, такого как класс или библиотека, хранящуюся в символе, обратно в строку, используя класс 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); }
Он должен произвести следующий вывод —