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
。該類定義方法:m1
,m2
和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");
}
}
以下程式碼在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