Äquivalent von C # 'readonly' Schlüsselwort in D?

7

Aus dem, was ich beim Lesen von D verstehe, muss bei Verwendung des Schlüsselworts immutable für eine Variable der Wert der Variablen zum Zeitpunkt der Kompilierung bekannt sein, während die C #% - Felder readonly und readonly nicht erforderlich sind kann in einem Klassenkonstruktor mit nicht statischen Werten zugewiesen werden. Ist das in D möglich?

    
Mark LeMoine 17.05.2011, 20:37
quelle

4 Antworten

6

Da es hinsichtlich der Unveränderlichkeit eine gewisse Verwirrung gibt (sowohl von der ursprünglichen Frage als auch von he_the_groests Kommentar), dachte ich, ich würde etwas hinzufügen.

Wenn Sie immutable int i = 42 sagen, sagen Sie, dass ich nicht geändert werde, nicht dass der Wert zur Kompilierzeit bekannt ist. immutable ist eigentlich ein Typmodifizierer und erstellt einen neuen Typ. immutable T ist eine Abkürzung für immutable(T) . immutable(T) erzeugt ein T, das niemals mutiert werden kann, das heißt, wenn Sie den Wert lesen und dann eine Funktion aufrufen, ist der Wert derselbe. Vergleichen Sie dies mit const(T) , was die schwächere Garantie dafür bietet, dass diese Instanz des Typs nicht geändert wird, aber jemand hat möglicherweise einen anderen Zugriff darauf. Wenn Sie also den Wert lesen und dann eine Funktion aufrufen, können Sie den Wert nicht annehmen wird gleich sein.

Im Allgemeinen immutable(T) != T . Es gibt jedoch bestimmte Situationen, in denen sie implizit ineinander umwandelbar sind. Wenn T ein Typ ist, der zum Beispiel keine "veränderbare Indirektion" haben soll. Das heißt, wenn ich eine Funktion an immutable(int) übergebe, erhalten sie eine Kopie - es gibt keine Möglichkeit, dass diese Funktion den übergebenen Wert ändern kann, wenn er kopiert wird - wenn das Typsystem dies nicht zulässt Es wäre einfach ärgerlich ohne zusätzliche Garantien, so dass das D-System es erlaubt. Wenn ich jedoch eine unveränderliche (int *) übergeben, kann diese kann durch die aufrufende Funktion geändert werden. Im Falle von Strukturen, wenn ein Mitglied eine veränderbare Indirektion hat, dann sagt man, dass die Struktur es auch hat.

Um also von der Theorie abzuweichen und zu praktischeren Dingen zurückzukehren, ist es nicht wahr, dass unveränderliche Werte zur Kompilierungszeit bekannt sein müssen und dass es keine gute Möglichkeit gibt, sie zu erstellen. Die einzige Mutation kann jedoch innerhalb des Konstruktors auftreten. Für einfache skalare Typen ist das ziemlich offensichtlich:

%Vor%

Aber was ist mit etwas wie einem Objekt? Nun, um einen Typ T zu konstruieren, verwenden wir

%Vor%

Um den Typ unveränderlich (T) zu konstruieren, verwenden wir

%Vor%

Hier ist ein vollständigeres kleines Beispiel

%Vor%

Wie Sie sehen können, kann Mutation innerhalb des Konstruktors auftreten. Sie können Membervariablen lesen, aber nicht schreiben (unveränderlich ist transitiv; dh jedes Mitglied (und jedes Mitglied von Mitgliedern) wird unveränderlich, wenn das übergeordnete Element. Sie können Methoden nur aufrufen, wenn sie als const .

Ich entschuldige mich für das off-topic Wandern, aber ich sehe, dass viele Leute in Bezug auf dieses Thema verwirrt zu sein scheinen.

    
Bernard 18.05.2011, 04:02
quelle
10

In D2 kann const-Member nur innerhalb des Konstruktors (oder direkt in der Klassendeklaration, aber nicht bei beiden) initialisiert werden:

%Vor%     
Raphaël Londeix 17.05.2011 22:06
quelle
3

fwend's Antwort ist im Prinzip tot, aber wenn Sie nach etwas weniger Ausgefallenem suchen, könnten Sie immer ein Mixin machen, um es zu automatisieren. Ungeprüfter Code unten, um die allgemeine Idee zu geben:

%Vor%

Verwendung:

%Vor%     
dsimcha 17.05.2011 21:51
quelle
2

Ich würde das Feld als privat deklarieren und dann einen get-Accessor verwenden, um es zu lesen

    
fwend 17.05.2011 21:24
quelle

Tags und Links