2017-11-11 8 views
3

Aus Neugier habe ich in dem folgenden Stück Code eingegeben:D - reine Klassen und Strukturen

pure struct Foo{ } 
pure class Bar{ } 

Diese anscheinend kompiliert sowohl mit DMD und LDC. Ich habe keine Ahnung, was es tut (wenn es das tut), da das Aufrufen unreiner Funktionen aus solchen Strukturen/Klassen OK ist. Also, was bewirkt eine Änderung der Klasse pure an einer Klasse oder einer Struktur?

Antwort

8

Im Allgemeinen haben D eine Tendenz Attribute zu ignorieren, wenn sie nicht gelten, wenn nichts anderes, weil generischer Code ist einfacher, so zu schreiben (at Mal, es vermeidet, eine Reihe von statischen ifs zu schreiben, nur um zu vermeiden, Attribute auf Code anzuwenden, wo sie keine Wirkung haben würden - ein Beispiel ist, dass Sie static auf eine ziemlich jede Deklaration auf Modulebene setzen können, aber es tut nicht mache eigentlich nichts für die meisten von ihnen, und der Compiler beklagt sich nicht darüber.

Aus welchen Gründen auch immer, die Art, wie Attribute angewendet werden, wenn Sie eine Struktur oder Klasse mit ihnen markieren, ist ein wenig inkonsistent. Wenn Sie beispielsweise eine Struktur oder Klasse mit @safe markiert haben, ist jede Funktion in dieser Struktur oder Klasse @safe, es sei denn, sie ist mit @trusted oder @system markiert. Im Gegensatz dazu, wenn Sie die Klasse oder Struktur mit pure markieren, tut es absolut nichts - genau wie mit static. Es wird einfach ignoriert.

Meine beste Vermutung, warum so etwas wie @safe zu allen Funktionen innerhalb der Struktur oder Klasse angelegt wird, während ein Attribut wie pure oder nothrow ignoriert wird, ist, dass @safe, @trusted und @system kann auf bestimmte Funktionen rückgängig gemacht wird innerhalb die Struktur oder Klasse, indem Sie explizit ein anderes Attribut für diese Funktion verwenden, während es für die meisten Attribute keine Möglichkeit gibt, sie umzukehren.

Leider kann die Tatsache, dass Sie eine Klasse oder Struktur mit Attributen markieren können, wenn sie entweder nicht gelten oder wenn sie nur auf die Deklarationen innerhalb der Klasse oder Struktur und nicht die Klasse oder Struktur selbst zu verwirren neigen Leute (zB denken manche Leute, dass immutable class C {..} etwas Besonderes für die Klasse bedeutet, wenn alles das bedeutet, dass die Deklarationen in der Klasse immutable sind; es wäre nicht anders als class C { immutable { ... } } zu tun). Letztendlich müssen Sie also wissen, was jedes Attribut tatsächlich zu tun hat, wenn es tatsächlich auf die Klasse oder Struktur angewendet wird, wenn es wirklich nur auf die Deklarationen innerhalb der Klasse oder Struktur angewendet wird und wenn sie einfach ignoriert werden.

Persönlich, ich Attribute nie auf eine Klasse oder Struktur, es sei denn, sie speziell für die Struktur oder Klasse und nicht auf die Funktionen innerhalb gelten soll (z. B. final auf eine Klasse bedeutet etwas anderes als das Aufsetzen auf die Funktionen innerhalb dieser Klasse) und die Anzahl der Attribute, die tatsächlich für eine Struktur oder Klasse gelten, ist ziemlich klein. static tut in einigen Kontexten (nur nicht auf Modulebene), abstract und final tun für Klassen, und die Zugriffsmodifikatoren (public, private, etc.) tun. Pro TDPL, synchronized soll auch speziell für die Klasse sein, aber synchronisierte Klassen wurden nie wirklich implementiert (nur synchronisierte Funktionen).Also, vielleicht habe ich eine verpasst, aber von meinem Kopf her ist das die vollständige Liste von Attributen, die tatsächlich auf eine Struktur oder Klasse angewendet werden können, und alle anderen werden entweder ignoriert oder auf die Deklarationen innerhalb der Struktur oder Klasse angewendet aber nicht zu der Struktur oder Klasse selbst.

2

Es ändert nichts. Der D-Compiler ignoriert einfach viele Schlüsselwörter, wenn sie an Orten platziert werden, an denen sie nicht sinnvoll sind.

Ein schneller Test zum Beweis:

pure struct S { 
    static void bar() {} 
} 

pure unittest { 
    static assert(!__traits(compiles, S.bar())); 
} 
+3

Sie könnten es noch direkter mit 'std.traits.functionAttributes' testen, die Ihnen die tatsächlichen Attribute der Funktion angibt. –

Verwandte Themen