it-swarm.com.de

Unterschied zwischen unveränderlich und const

Ich habe oft gesehen, dass die Begriffe immutable und const synonym verwendet wurden. Nach meiner (kleinen) Erfahrung unterscheiden sich die beiden jedoch stark in dem 'Vertrag', den sie im Code abschließen:

Unveränderlich macht den Vertrag, dass sich dieses Objekt nicht ändert, was auch immer (z. B. Python Tupel, Java Strings)).

Const schließt den Vertrag ab, dass er im Rahmen dieser Variablen nicht geändert wird (keine Zusage darüber, was andere Threads mit dem 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 Single-Threaded (PHP) oder verfügt entweder über ein lineares oder ein eindeutiges Typisierungssystem (Clean, Mercury, ATS).

Ist mein Verständnis dieser beiden Konzepte richtig?

Zweitens, wenn es einen Unterschied gibt, warum werden sie fast ausschließlich austauschbar verwendet?

30
K.Steff

Ich werde mit C++ sprechen, wo dieser Unterschied am relevantesten ist.

Wie Sie richtig bemerken, bedeutet nveränderlich, dass sich ein Objekt nach seiner Erstellung überhaupt nicht ändern kann. Diese Erstellung kann natürlich zur Laufzeit erfolgen, d. H. 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:

  1. Es wurden keine Mitglieder als mutable deklariert, die durch const Mitgliedsfunktionen mutiert sind

  2. Es wird als const deklariert

  3. const Mitgliedsfunktionen verwenden nicht const_cast, um die Qualifikation const zu entfernen, um Mitglieder zu mutieren

Sie können jedoch auch Zugriffsmodifikatoren in Betracht ziehen: Wenn eine Operation eine Instanz intern mutiert, aber keinen Einfluss auf den Status der Instanz hat, der über ihre öffentliche Schnittstelle beobachtet werden kann, ist das Objekt „logisch unveränderlich“.

C++ bietet also die Tools, die zum Erstellen unveränderlicher Objekte erforderlich sind. Wie fast alles in C++ sind die Tools jedoch nur minimal ausreichend und erfordern Sorgfalt bei der tatsächlichen Verwendung. Der Status einer Instanz ist nicht unbedingt auf die Instanzmitgliedsvariablen beschränkt. Da C++ keine Möglichkeit bietet, referenzielle Transparenz zu erzwingen, kann es auch den globalen Status oder den Klassenstatus enthalten.

const hat in C++ auch eine andere Funktion: Qualifizieren von Referenzen und Zeigern. Eine const Referenz kann sich auf ein Nicht-const Objekt beziehen. Es ist legal (obwohl nicht generell notwendig oder ratsam), const_cast Zu verwenden, um ein Objekt durch eine const - Referenz zu mutieren. genau dann, wenn dieses Objekt wird als nicht deklariert. const:

int        i = 4;         // Non-const object.
const int* p = &i;        // const pointer.

*const_cast<int*>(p) = 5; // Legal.

Und natürlich ist es undefiniertes Verhalten, ein const Objekt zu mutieren:

const int  i = 4;         // const object.
const int* p = &i;        // const pointer.

*const_cast<int*>(p) = 5; // Illegal.
15
Jon Purdy

Wenn Sie für Java, wobei das Schlüsselwort "final" "const" darstellt, denken Sie an:

final Person someone = new Person();

Dies bedeutet, dass someone NIEMALS auf ein anderes Personenobjekt verweisen kann. Sie können jedoch weiterhin Details der überwiesenen Person ändern. Z.B. someone.setMonthlySalary(10000);

Wenn someone jedoch ein "unveränderliches" Objekt wäre, wäre eine der folgenden Aussagen zutreffend: (a) Sie hätten keine Methode mit dem Namen setMonthlySalary (b) Das Aufrufen von setMonthlySalary würde immer eine Ausnahme auslösen wie UnsupportedOperationException

20
rationalrevolt

Unveränderliche Objekte sind solche, deren Status sich nach dem Erstellen nicht ändert. Zum Beispiel;

string prefix = "Pre";
string postfix = "Post";
string myComplexStr = prefix + postfix;

In diesem Beispiel ist das myComplexStr-Objekt unveränderlich, aber nicht konstant, da sein Wert berechnet wird. Und es ist unveränderlich, weil es eine Zeichenfolge 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 der Kompilierung 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.

10
Mert Akcakaya

Ist mein Verständnis dieser beiden Konzepte richtig?

Ja, aber Ihre zweite Frage zeigt, dass Sie diese Unterschiede nicht verstehen.

Zweitens, wenn es einen Unterschied gibt, warum werden sie fast ausschließlich austauschbar verwendet?

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 selbst vollständig von den Daten getrennt ist. Sie können beispielsweise einige Daten bearbeiten und dann über eine const-Referenz verfügbar machen. Der Zugriff ist schreibgeschützt, aber die Daten selbst, da alle Daten veränderbar sind.

const nur Zugriffsbeschränkungen für Garantien, während nveränderlichkeit (wie zum Beispiel in D) wirklich keine Möglichkeit impliziert, 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 auf const zugegriffen werden kann, und sicherstellen, dass sie initialisiert und dann nicht mehr berührt werden. Dies ist jedoch keine starke Garantie, da Sie Sprachen wie D erhalten, wenn Sie Ihre Daten als unveränderlich markieren. Die Sprache stellt sicher, dass es überhaupt nicht möglich ist, diese Daten zu ändern, während Sie in C++ möglicherweise noch in der Lage sind, die Daten durch const Casting und Mutability zu ändern, falls dies wirklich erforderlich ist.

Am Ende es ist überhaupt nicht dasselbe da es überhaupt nicht die gleichen Garantien bietet.

10
Klaim

Apropos JavaScript, die Schlüsselwörter const und Object.freeze

const gilt für Bindungen variables. Es wird eine unveränderliche Bindung erstellt, der Sie keinen neuen Wert zuweisen können.

Object.freeze arbeitet mit Objektwerten. Es macht ein Objekt nveränderlich. Sie können nämlich seine Eigenschaften nicht ändern.

3
zangw

In C++ sind sie gleich. Sie können ein const -Objekt zwar ändern, wenn Sie den Speicherort im Speicher und die Berechtigung des Betriebssystems zum Schreiben in diesen Speicher haben.

0
Martin Beckett

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, erhalten Sie ein undefiniertes Verhalten. (Sie können versuchen, um 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 die Konstante hingegen teilt dem Compiler lediglich mit, dass Sie diesen Zeiger oder diese Referenz 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 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, Sie erhalten jedoch 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 einschränken" 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 einschränken" im Gültigkeitsbereich befindet, erhalten Sie ein undefiniertes Verhalten. Dies ist stärker als ein const-Zeiger, der Sie nur daran hindert, ein Objekt über diesen Zeiger zu ändern.

0
gnasher729