2010-09-10 8 views
10

Ich lerne gerade D, und eines der Dinge, über die ich mich gewundert habe, ist, ob D eine Möglichkeit hat, die Codegenerierungsfunktionen von JVM-Sprachen zu duplizieren.Kompiliere Timecode-Generierung in D

Hier ist ein Szenario: Ich habe ein Objekt, und ich möchte eine Zeichenfolge basierend auf diesem Objekt generieren, die seinen Namen und alle seine Felder gibt. In Java/Scala, ich könnte nur Reflexion verwenden, aber angenommen, Geschwindigkeit ist ein Problem. Ich könnte eine Bytecode-Generierungsbibliothek verwenden, um dynamisch eine Klasse zu generieren und zu kompilieren, die dies ohne Reflektion tut. Die Implementierung würde dazu führen, dass die Felder des Objekts durchlaufen und der Name durch Rekursion abgerufen wird und diese Informationen verwendet werden, um dynamisch Java (oder Bytecode) zu generieren, der direkt auf die Felder zugreift.

Wenn Sie dieses Szenario nicht mögen, weil es schwach und/oder unrealistisch ist, ist eine andere, die realistischer sein könnte, eine optimierte Objektserialisierung.

Ich habe Beispiele gesehen, wo D's Kompilierzeit Auswertung und/oder Vorlage Metaprogrammierung für Dinge wie Vorberechnung der Fibonacci-Sequenz zur Kompilierzeit und andere rekursive Algorithmen verwendet wird, aber gibt es eine Möglichkeit, solche Dinge nur mit der Sprache zu tun und einen Compiler, oder müssten Sie einen separaten Code-Generator entwickeln und ihn vor dem Compiler ausführen, um diese Art von Funktionalität zu erhalten?

Antwort

5

String-Mixins können auf den Namensraum zugreifen, in den sie gemischt sind. Dazu gehört this.tupleof, mit dem die Felder einer Klasse iteriert werden können. Eine Serialisierungsvorlage könnte dies ausnutzen oder den Benutzer auf andere Weise zwingen, die zu serialisierenden Felder per Hand anzugeben; dh. class Class : ISerializable { int foo; Forble bar; mixin(genSerialize("foo, bar")); ... }

6

Nicht nur das ist möglich, es ist praktisch für Sie in D2 getan. Alles, was Sie brauchen, ist ein kleines Mixin, um diese von Kompilier-Features in Runtime-Features zu verwandeln.

  • Für den Klassennamen, alles, was Sie tun müssen, ist typeof(this).stringof innerhalb des Anwendungsbereichs der Klasse zu bewerten.

  • Für eine Liste aller Felder, versuchen Sie __traits(allMembers, typeof(this)) und dann filtern Sie die Sachen, die kein Feld ist (std.traits wird hier nützlich sein).

+0

Bitte, können Sie dies [Post] (http://stackoverflow.com/questions/11314596/listing-a-classs-methods-trough-mixin) berücksichtigen? – menjaraz