Ich habe die Begriffe oft gesehen immutable
und const
synonym verwendet. Nach meiner (geringen) Erfahrung unterscheiden sich die beiden jedoch stark in dem Vertrag, den sie im Code schließen:
Unveränderlich macht der Vertrag, dass sich dieses Objekt überhaupt nicht ändert (zB Python-Tupel, Java-Strings).
Const schließt den Vertrag, dass im Gültigkeitsbereich dieser Variablen keine Änderungen vorgenommen werden (keine Zusicherung darüber, was andere Threads für das Objekt tun könnten, auf das in diesem Zeitraum verwiesen wird, z. B. das Schlüsselwort C / C ++).
Offensichtlich sind die beiden nicht gleichwertig, es sei denn, die Sprache ist ein Singlethread (PHP) oder sie verfügt über ein lineares oder eindeutiges Typisierungssystem (Clean, Mercury, ATS).
Erstens, ist mein Verständnis dieser beiden Konzepte korrekt?
Zweitens, wenn es einen Unterschied gibt, warum werden sie fast ausschließlich austauschbar verwendet?
quelle
const
gibt es nicht in jeder Sprache und Veränderlichkeit und Unveränderlichkeit gibt es nicht in jeder Sprache, so dass diese Sprache nicht agonistisch ist. Es ist nur sprachspezifisch , wo diese Konzepte zutreffen.Antworten:
Ich werde mit C ++ sprechen, wo dieser Unterschied am relevantesten ist.
Wie Sie richtig bemerken, bedeutet unveränderlich , dass sich ein Objekt nach seiner Erstellung überhaupt nicht ändern kann. Diese Erstellung kann natürlich zur Laufzeit erfolgen, dh ein
const
Objekt ist nicht unbedingt eine Konstante zur Kompilierungszeit. In C ++ ist ein Objekt unveränderlich, wenn (1) und entweder (2) oder (3) erfüllt sind:Es wurden keine Mitglieder deklariert
mutable
, die durchconst
Mitgliederfunktionen mutiert sindEs ist deklariert
const
const
Mitgliedsfunktionen werden nichtconst_cast
zum Entfernen vonconst
Qualifikationen verwendet, um Mitglieder zu mutierenSie können jedoch auch Zugriffsmodifikatoren in Betracht ziehen: Wenn eine Operation eine Instanz intern mutiert, sich jedoch nicht auf den über die öffentliche Schnittstelle beobachtbaren Zustand der Instanz auswirkt, ist das Objekt „logisch unveränderlich“.
Daher bietet C ++ die Tools, die zum Erstellen unveränderlicher Objekte erforderlich sind. Wie die meisten anderen Tools in C ++ sind die Tools jedoch nur minimal ausreichend und erfordern Sorgfalt, um sie tatsächlich zu verwenden. Der Status einer Instanz ist nicht notwendigerweise auf die Instanzmitgliedsvariablen beschränkt - da C ++ keine Möglichkeit bietet, referenzielle Transparenz zu erzwingen, kann er auch den globalen Status oder den Klassenstatus enthalten.
const
hat auch eine andere Funktion in C ++: Referenzen und Zeiger zu qualifizieren. Eineconst
Referenz kann sich auf ein Nichtobjekt beziehenconst
. Es ist legal (obwohl im Allgemeinen nicht notwendig oder ratsam),const_cast
ein Objekt durch einenconst
Verweis zu mutieren , wenn und nur wenn dieses Objekt als nicht deklariert wirdconst
:Und natürlich ist es undefiniertes Verhalten, ein
const
Objekt zu mutieren :quelle
Wenn Sie für Java sprechen, wobei das Schlüsselwort "final" für "const" steht, sollten Sie Folgendes berücksichtigen:
Dies bedeutet, dass
someone
NIEMALS auf ein anderes Personenobjekt verwiesen werden darf. Sie können jedoch die Details der überwiesenen Person ändern. Z.Bsomeone.setMonthlySalary(10000);
Wenn es sich
someone
jedoch um ein "unveränderliches" Objekt handelt, ist eine der folgendensetMonthlySalary
Bedingungen erfüllt : (a) Sie hätten keine Methode mit dem Namen (b) Der Aufruf von setMonthlySalary würde immer eine Ausnahme auslösen, zUnsupportedOperationException
quelle
Unveränderliche Objekte sind Objekte, deren Status sich nach dem Erstellen nicht ändert. Beispielsweise;
In diesem Beispiel ist das myComplexStr-Objekt unveränderlich, aber nicht konstant, da sein Wert berechnet wird. Und es ist unveränderlich, weil es ein String ist, eine statische Längeneigenschaft hat und sich nicht ändern kann.
Const-Objekte werden im Allgemeinen verwendet, um einige reale Konstanten zu identifizieren, deren Werte vor dem Kompilieren bekannt sind, z. B. Pi, "USA", "StackOverflow.com", Portnummern usw.
Aus dieser Perspektive unterscheidet sich Const von unveränderlichen Objekten, da ihre Werte nicht vom Programm berechnet werden.
Wenn Sie jedoch über das Schlüsselwort "const" in C ++ sprechen, können Sie sagen, dass "const" zum Erstellen unveränderlicher Objekte verwendet wird.
quelle
const
Verhaltens ist undefiniert, egal wo es zugeordnet ist, IIRC. Undefiniertes Verhalten ist schlimmer als ein bestimmter Fehler, der garantiert auftritt. Es bedeutet, dass Sie C ++ nicht mehr verwenden - C ++ bietet keine Möglichkeit, einenconst
Wert zu ändern (außermutable
natürlich Mitglieder, aber das ist nicht Ihr Punkt), was C ++ betrifft, können Sie dies nicht tun. Welche spezifischen Implementierungen dies zulassen, ist eine ganz andere Sache (und ich wette, wenn Sie mit Optimierungen kompilieren, hat der Stunt, den Sie gezogen haben, keinen Einfluss auf spätere Ausdrücke,pi
da er ersetzt wurde).Ja, aber Ihre zweite Frage zeigt, dass Sie diese Unterschiede nicht verstehen.
const
in C ++ wird nur für die Zugriffsebene verwendet (es bedeutet "schreibgeschützt") , nicht für die Unveränderlichkeit. Dies bedeutet, dass der Zugriff von den Daten völlig getrennt ist. Beispielsweise könnten Sie einige Daten manipulieren und sie dann über eine konstante Referenz verfügbar machen. Der Zugriff ist schreibgeschützt, aber die Daten selbst, da alle Daten veränderbar sind.const garantiert nur Zugriffsbeschränkungen, während Unveränderlichkeit (wie zum Beispiel in D) wirklich keine Möglichkeit bedeutet, die Daten in irgendeinem Stadium der Lebensdauer des Objekts zu ändern .
Jetzt können Sie die Unveränderlichkeit in C ++ simulieren, indem Sie sicherstellen, dass auf einige Daten nur mit const zugegriffen werden kann, und sicherstellen, dass sie initialisiert und dann nicht mehr berührt werden. Dies ist jedoch keine Garantie, da Sprachen wie D Ihnen dies ermöglichen, wenn Sie Ihre Daten als unveränderlich markieren. Die Sprache stellt sicher, dass es überhaupt nicht möglich ist, Operationen durchzuführen, die diese Daten ändern, während Sie in C ++ die Daten möglicherweise noch durch Const Casting und Mutability ändern können, falls dies wirklich notwendig ist.
Am Ende ist es überhaupt nicht dasselbe, wie es überhaupt nicht die gleichen Garantien bietet.
quelle
Apropos JavaScript, die Schlüsselwörter
const
undObject.freeze
const
gilt für bindungenvariables
. Es wird eine unveränderliche Bindung erstellt, der Sie keinen neuen Wert zuweisen können.Object.freeze
Arbeitet mit Objektwerten. Es macht ein Objekt unveränderlich . Sie können nämlich seine Eigenschaften nicht ändern.quelle
In C ++ sind sie gleich. Obwohl Sie ein
const
Objekt ändern können, wenn Sie dessen Speicherort und Betriebssystemberechtigung zum Schreiben in diesen Speicher haben.quelle
In C, C ++ und verwandten Sprachen gibt es auch einen Unterschied zwischen einem Objekt, das const ist, und Ihrer Referenz oder Ihrem Zeiger auf das Objekt, das eine konstante Referenz ist.
Wenn Sie versuchen, ein konstantes Objekt zu ändern, tritt ein undefiniertes Verhalten auf. (Sie können versuchen , ein konstantes Objekt zu ändern, indem Sie beispielsweise seine Adresse übernehmen, die Adresse in einen Nicht-Konstanten-Zeiger umwandeln und dann diesen Nicht-Konstanten-Zeiger verwenden, um das Objekt zu ändern.)
Der konstante Zeiger oder Verweis auf der anderen Seite teilt dem Compiler lediglich mit, dass Sie diesen Zeiger oder Verweis nicht zum Ändern des Objekts verwenden können. Sie können den Zeiger oder die Referenz umwandeln und versuchen, das Objekt zu ändern. Wenn das Objekt selbst konstant war, werden schlimme Dinge passieren. Wenn das Objekt nicht konstant war, ändert es sich. Dies kann natürlich die Benutzer Ihres Codes verwirren und möglicherweise Fehler verursachen.
Wenn Sie in C ein Zeichenfolgenliteral wie "Hallo" verwenden, sind die fünf Zeichen und die nachfolgenden Nullbytes tatsächlich konstant, aber Sie erhalten einen Nicht-Konstanten-Zeiger. Sehr schlechte Idee, diesen Nicht-Konstanten-Zeiger zu verwenden, um das Objekt zu ändern.
In C können Sie einen Zeiger "const restrict" haben. Das heißt, das Objekt, auf das gezeigt wird, ist vorübergehend konstant. Wenn das Objekt auf irgendeine Weise geändert wird, während sich der Zeiger "const restrict" im Gültigkeitsbereich befindet, tritt undefiniertes Verhalten auf. Dies ist stärker als ein const-Zeiger, der nur verhindert, dass Sie ein Objekt über diesen Zeiger ändern.
quelle