Dart 程式設計 - 符號



Dart 中的符號是不透明的,動態字串名稱,用於從庫中反射元資料。簡單來說,符號是一種儲存人類可讀字串與計算機最佳化使用字串之間關係的方式。

反射是一種在執行時獲取型別元資料(例如類中的方法數量、它具有的建構函式數量或函式中的引數數量)的機制。您甚至可以呼叫在執行時載入的型別的某個方法。

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

語法

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

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

示例

考慮以下示例。程式碼在庫 foo_lib 中聲明瞭一個類 Foo。該類定義了方法 m1、m2m3

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

以下程式碼載入 Foo.dart 庫並搜尋 Foo 類,藉助 Symbol 型別。由於我們正在從上述庫反射元資料,因此程式碼匯入了 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     
廣告