Programación de dardos - Símbolo

Los símbolos en Dart son nombres de cadenas dinámicos y opacos que se utilizan para reflejar los metadatos de una biblioteca. En pocas palabras, los símbolos son una forma de almacenar la relación entre una cadena legible por humanos y una cadena que está optimizada para ser utilizada por computadoras.

La reflexión es un mecanismo para obtener metadatos de un tipo en tiempo de ejecución, como el número de métodos en una clase, el número de constructores que tiene o el número de parámetros en una función. Incluso puede invocar un método del tipo que se carga en tiempo de ejecución.

En Dart Reflexión, las clases específicas están disponibles en el dart:mirrorspaquete. Esta biblioteca funciona tanto en aplicaciones web como en aplicaciones de línea de comandos.

Sintaxis

Symbol obj = new Symbol('name');  
// expects a name of class or function or library to reflect

los name debe ser un nombre de miembro público de Dart, un nombre de constructor público o un nombre de biblioteca válido.

Ejemplo

Considere el siguiente ejemplo. El código declara una claseFoo en una biblioteca foo_lib. La clase define los métodosm1, m2, y 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"); 
   } 
}

Se carga el siguiente código Foo.dartbiblioteca y busca la clase Foo, con la ayuda del tipo de símbolo. Dado que estamos reflejando los metadatos de la biblioteca anterior, el código se importadart:mirrors biblioteca.

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; 
   } 
}

Tenga en cuenta que la línea libMirror.declarations.forEach ((s, d) => print (s)); iterará a través de cada declaración en la biblioteca en tiempo de ejecución e imprimirá las declaraciones como tipo deSymbol.

Este código debería producir lo siguiente output -

Found Library 
checkng...class details.. 
No of classes found is : 1 
Symbol("Foo") // class name displayed as symbol  
class found.

Ejemplo: muestra el número de métodos de instancia de una clase

Consideremos ahora mostrar el número de métodos de instancia en una clase. La clase predefinidaClassMirror nos ayuda a lograr lo mismo.

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)); 
   } 
}

Este código debería producir lo siguiente output -

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")

Convertir símbolo en cadena

Puede convertir el nombre de un tipo como clase o biblioteca almacenada en un símbolo de nuevo en cadena usando MirrorSystemclase. El siguiente código muestra cómo puede convertir un símbolo en una cadena.

import 'dart:mirrors'; 
void main(){ 
   Symbol lib = new Symbol("foo_lib"); 
   String name_of_lib = MirrorSystem.getName(lib); 
   
   print(lib); 
   print(name_of_lib); 
}

Debería producir lo siguiente output -

Symbol("foo_lib")   

foo_lib