Programmation de fléchettes - Symbole

Les symboles dans Dart sont des noms de chaîne opaques et dynamiques utilisés pour refléter les métadonnées d'une bibliothèque. En termes simples, les symboles sont un moyen de stocker la relation entre une chaîne lisible par l'homme et une chaîne optimisée pour être utilisée par les ordinateurs.

La réflexion est un mécanisme pour obtenir des métadonnées d'un type à l'exécution comme le nombre de méthodes dans une classe, le nombre de constructeurs dont elle dispose ou le nombre de paramètres dans une fonction. Vous pouvez même appeler une méthode du type qui est chargée au moment de l'exécution.

Dans la réflexion Dart, des classes spécifiques sont disponibles dans le dart:mirrorspaquet. Cette bibliothèque fonctionne à la fois dans les applications Web et les applications de ligne de commande.

Syntaxe

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

le name doit être un nom de membre Dart public valide, un nom de constructeur public ou un nom de bibliothèque.

Exemple

Prenons l'exemple suivant. Le code déclare une classeFoo dans une bibliothèque foo_lib. La classe définit les méthodesm1, m2, et 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"); 
   } 
}

Le code suivant se charge Foo.dartbibliothèque et recherche la classe Foo, à l'aide du type Symbol. Puisque nous reflétons les métadonnées de la bibliothèque ci-dessus, le code importedart:mirrors bibliothèque.

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

Notez que la ligne libMirror.declarations.forEach ((s, d) => print (s)); itérera à travers chaque déclaration de la bibliothèque au moment de l'exécution et imprimera les déclarations comme type deSymbol.

Ce code devrait produire les éléments suivants output -

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

Exemple: afficher le nombre de méthodes d'instance d'une classe

Considérons maintenant l'affichage du nombre de méthodes d'instance dans une classe. La classe prédéfinieClassMirror nous aide à réaliser la même chose.

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

Ce code devrait produire les éléments suivants 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 le symbole en chaîne

Vous pouvez convertir le nom d'un type comme une classe ou une bibliothèque stockée dans un symbole en chaîne en utilisant MirrorSystemclasse. Le code suivant montre comment vous pouvez convertir un symbole en chaîne.

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

Il devrait produire ce qui suit output -

Symbol("foo_lib")   

foo_lib