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
コメントを残す