Dart编程符号


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

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

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

语法

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

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

请考虑以下示例。代码在库foo_lib中声明了一个类Foo。该类定义方法m1m2m3

Foo.dart

library foo_lib;   
// 库名称是一个symbol   

class Foo {         
 // 类名称是一个symbol  
 m1() {        
    // 方法名是一个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");   
   //库名称被存储为一个Symbol

   Symbol clsToSearch = new Symbol("Foo");  
   // 类名称被存储为一个Symbol  

   if(checkIf_classAvailableInlibrary(lib, clsToSearch))  
      // 在foo_lib库中搜索Foo类
      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