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を宣言しています。このクラスは、メソッドm1m2、および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
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です