Dart-programming-symbol

提供:Dev Guides
移動先:案内検索

Dartプログラミング-シンボル

Dartのシンボルは、ライブラリのメタデータを反映するために使用される不透明で動的な文字列名です。 簡単に言えば、シンボルは、人間が読める文字列とコンピューターで使用するために最適化された文字列との関係を保存する方法です。

リフレクションは、クラス内のメソッドの数、クラスに含まれるコンストラクターの数、関数内のパラメーターの数など、実行時に型のメタデータを取得するメカニズムです。 実行時にロードされるタイプのメソッドを呼び出すこともできます。

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

次のコードは、 Foo.dart ライブラリをロードし、Symbolタイプを使用して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")

シンボルを文字列に変換

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

次の output が生成されるはずです-

Symbol("foo_lib")

foo_lib