Dart符號(Symbol)


Dart中的符號(Symbol)是不透明的動態字串名稱,用於反映庫中的後設資料。簡而言之,符號是一種儲存人類可讀字串與優化供計算機使用的字串之間關係的方法。

反射是一種在執行時獲取型別後設資料的機制,如類中的方法數,它具有的建構函式數或函式中的引數數。甚至可以呼叫在執行時載入的型別的方法。

在Dart反射中,dart:mirrors包中提供了特定的類。此庫適用於Web應用程式和命令列應用程式。

語法

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

name必須是有效的公共Dart成員名稱,公共建構函式名稱或庫名稱。

範例
請考慮以下範例。程式碼在庫foo_lib中宣告了一個類Foo。該類定義方法:m1m2m3

檔案: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"); 
   } 
}

以下程式碼在Symbol型別的幫助下載入Foo.dart庫並搜尋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")

將Symbol轉換為字串

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