Dart 编程 - 符号

Dart 中的符号是不透明的动态字符串名称,用于从库中反映出元数据。简而言之,符号是一种存储人类可读字符串与优化为计算机使用的字符串之间关系的方法。

反射是一种在运行时获取类型元数据的机制,例如类中的方法数量、其具有的构造函数数量或函数中的参数数量。您甚至可以调用在运行时加载的类型的方法。

在 Dart 反射中,dart:mirrors 包中提供了特定类。此库适用于 Web 应用程序和命令行应用程序。

语法

Symbol obj = new Symbol('name');
// 期望类、函数或库的名称能够反映

name 必须是有效的公共 Dart 成员名称、公共构造函数名称或库名称。

示例

考虑以下示例。代码在库 foo_lib 中声明类 Foo。该类定义方法 m1、m2m3

Foo.dart

library foo_lib;
// 库名称可以是符号  

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 库并借助 Symbol 类型搜索 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")

将符号转换为字符串

您可以使用 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