Was bedeutet unveränderlich?


103

Wenn eine Zeichenfolge unveränderlich ist, bedeutet das, dass ... (nehmen wir JavaScript an)

var str = 'foo';

alert(str.substr(1)); // oo

alert(str); // foo

Bedeutet dies, dass beim Aufrufen von Methoden für eine Zeichenfolge die geänderte Zeichenfolge zurückgegeben wird, die ursprüngliche Zeichenfolge jedoch nicht geändert wird?

Wenn der String veränderlich wäre, würde das bedeuten, dass auch der zweite zurückkehren alert()würde oo?

Antworten:


104

Sobald Sie das Objekt instanziiert haben, können Sie seine Eigenschaften nicht mehr ändern. In Ihrer ersten Warnung ändern Sie nicht foo. Sie erstellen eine neue Zeichenfolge. Aus diesem Grund wird in Ihrer zweiten Warnung "foo" anstelle von "oo" angezeigt.

Bedeutet dies, dass beim Aufrufen von Methoden für eine Zeichenfolge die geänderte Zeichenfolge zurückgegeben wird, die ursprüngliche Zeichenfolge jedoch nicht geändert wird?

Ja. Nichts kann die Zeichenfolge ändern, sobald sie erstellt wurde. Dies bedeutet nicht, dass Sie der strVariablen kein neues Zeichenfolgenobjekt zuweisen können. Sie können das aktuelle Objekt, auf das str verweist, einfach nicht ändern.

Wenn die Zeichenfolge veränderbar wäre, würde dies bedeuten, dass die 2. Warnung () ebenfalls oo zurückgibt?

Technisch gesehen nein, da die Teilstring-Methode eine neue Zeichenfolge zurückgibt. Wenn Sie ein Objekt veränderbar machen, ändert sich die Methode nicht. Wenn Sie es veränderbar machen, können Sie es technisch so gestalten, dass die Teilzeichenfolge die ursprüngliche Zeichenfolge ändert, anstatt eine neue zu erstellen.


Wenn dieselbe Zeichenfolge geändert und zugewiesen wird, wird die Zeichenfolge var str = 'foo' aktualisiert. str = str (1)); // oo alert (str); // oo
Ashwin G

Was ist mit dem folgenden Code? Der Zeichenfolgenwert wird jetzt geändert. var name = "Santosh"; console.log (name.substr (0,2)); var name = "kumar" console.log (name); Wie es immer noch unveränderlich ist
Santosh

97

Auf einer niedrigeren Ebene bedeutet Unveränderlichkeit, dass der Speicher, in dem die Zeichenfolge gespeichert ist, nicht geändert wird. Sobald Sie eine Zeichenfolge erstellt haben "foo", wird Speicher zum Speichern des Werts zugewiesen "foo". Dieser Speicher wird nicht verändert. Wenn Sie die Zeichenfolge beispielsweise mit ändern, substr(1)wird eine neue Zeichenfolge erstellt und ein anderer Teil des Speichers zugewiesen, der gespeichert wird "oo". Jetzt haben Sie zwei Zeichenfolgen im Speicher, "foo"und "oo". Selbst wenn Sie es nicht mehr verwenden, "foo"bleibt es so lange bestehen, bis der Müll gesammelt ist.

Ein Grund, warum String-Operationen vergleichsweise teuer sind.


1
Zahlen sind auch unveränderlich.
RN Kushwaha

3
Hallo ab 2015 !! "Auf einer niedrigeren Ebene bedeutet Unveränderlichkeit, dass der Speicher, in dem die Zeichenfolge gespeichert ist, nicht geändert wird." --- Dies ist zu restriktiv und klingt nicht richtig. Bei der Unveränderlichkeit geht es nur um das Benutzerland. Der virtuelle Speicher kann nach Belieben geändert werden, sobald die Sprachspezifikationsinvarianten erhalten bleiben.
Zerkms

2
Diese Antwort ist logischer als die akzeptierte Antwort.
Ejaz Karim

Aber ich kann wie var str = 'foo' tun; Ich kann über str = 'bar' ändern. Der str-Wert wurde auf diese Weise geändert, oder?
Hacker

@ Hacker Nein. Sie haben der Variablen, die auf eine neue Position im Speicher verweist, eine neue Zeichenfolge zugewiesen.
Täuschung

13

Unveränderlich bedeutet das, was nicht geändert oder modifiziert werden kann.

Wenn Sie also einer Zeichenfolge einen Wert zuweisen, wird dieser Wert von Grund auf neu erstellt und nicht ersetzt. Jedes Mal, wenn ein neuer Wert derselben Zeichenfolge zugewiesen wird, wird eine Kopie erstellt. In Wirklichkeit ändern Sie also niemals den ursprünglichen Wert.


9

Ich bin mir bei JavaScript nicht sicher, aber in Java machen Strings mit dem "String Constant Pool" einen zusätzlichen Schritt zur Unveränderlichkeit. Strings können mit String-Literalen ( "foo") oder mit einem StringKlassenkonstruktor erstellt werden. Mit Zeichenfolgenliteralen erstellte Zeichenfolgen sind Teil des Zeichenfolgenkonstantenpools, und dasselbe Zeichenfolgenliteral ist immer dieselbe Speicheradresse aus dem Pool.

Beispiel:

    String lit1 = "foo";
    String lit2 = "foo";
    String cons = new String("foo");

    System.out.println(lit1 == lit2);      // true
    System.out.println(lit1 == cons);      // false

    System.out.println(lit1.equals(cons)); // true

Oben werden beide lit1und lit2mit demselben Zeichenfolgenliteral erstellt, sodass sie auf dieselbe Speicheradresse zeigen. lit1 == lit2ergibt sich true, weil sie genau das gleiche Objekt sind.

Wird consjedoch mit dem Klassenkonstruktor erstellt. Obwohl der Parameter dieselbe Zeichenfolgenkonstante ist, weist der Konstruktor neuen Speicher zu cons, was bedeutet, dass er consnicht dasselbe Objekt wie lit1und ist lit2, obwohl er dieselben Daten enthält.

Da die drei Zeichenfolgen alle dieselben Zeichendaten enthalten, gibt die Verwendung der equalsMethode natürlich true zurück.

(Beide Arten der Saitenkonstruktion sind natürlich unveränderlich)


3

Unveränderlich bedeutet, dass der Wert nicht geändert werden kann. Einmal erstellt, kann ein String-Objekt nicht mehr als unveränderlich geändert werden. Wenn Sie einen Teilstring eines Strings anfordern, wird ein neuer String mit dem angeforderten Teil erstellt.

Die Verwendung von StringBuffer während der Bearbeitung von Strings macht die Operation effizienter, da StringBuffer die Zeichenfolge in einem Zeichenarray mit Variablen speichert, um die Kapazität des Zeichenarrays und die Länge des Arrays zu speichern (Zeichenfolge in Form eines Zeichenarrays).


3

Die Lehrbuchdefinition der Veränderlichkeit kann oder kann geändert oder geändert werden. In der Programmierung bezeichnen wir mit dem Wort Objekte, deren Zustand sich im Laufe der Zeit ändern darf. Ein unveränderlicher Wert ist genau das Gegenteil - nachdem er erstellt wurde, kann er sich nie mehr ändern.

Wenn dies seltsam erscheint, möchte ich Sie daran erinnern, dass viele der Werte, die wir ständig verwenden, tatsächlich unveränderlich sind.

var statement = "I am an immutable value";
var otherStr = statement.slice(8, 17);

Ich denke, niemand wird überrascht sein zu erfahren, dass die zweite Zeile die Zeichenfolge in der Anweisung in keiner Weise ändert. Tatsächlich ändern keine Zeichenfolgenmethoden die Zeichenfolge, mit der sie arbeiten, sondern alle geben neue Zeichenfolgen zurück. Der Grund ist, dass Strings unveränderlich sind - sie können sich nicht ändern, wir können immer nur neue Strings erstellen.

Zeichenfolgen sind nicht die einzigen unveränderlichen Werte, die in JavaScript integriert sind. Zahlen sind auch unveränderlich. Können Sie sich überhaupt eine Umgebung vorstellen, in der die Auswertung des Ausdrucks 2 + 3 die Bedeutung der Zahl 2 ändert? Es klingt absurd, aber wir tun dies die ganze Zeit mit unseren Objekten und Arrays.


2

Von Strings zu Stacks ... ein einfach zu verstehendes Beispiel aus Eric Lipperts Blog :

Pfadfindung mit A * in C # 3.0, Teil 2 ...

Ein veränderlicher Stack wie System.Collections.Generic.Stack ist eindeutig nicht geeignet. Wir möchten in der Lage sein, einen vorhandenen Pfad zu übernehmen und daraus neue Pfade für alle Nachbarn seines letzten Elements zu erstellen, aber das Verschieben eines neuen Knotens auf den Standardstapel ändert den Stapel. Wir müssten Kopien des Stapels erstellen, bevor wir ihn verschieben, was albern ist, weil wir dann den gesamten Inhalt unnötig duplizieren würden.

Unveränderliche Stapel haben dieses Problem nicht. Wenn Sie auf einen unveränderlichen Stapel schieben, wird lediglich ein brandneuer Stapel erstellt, der mit dem alten Stapel verbunden ist. Da der Stapel unveränderlich ist, besteht keine Gefahr, dass ein anderer Code hinzukommt und den Endinhalt durcheinander bringt. Sie können den alten Stapel nach Herzenslust weiter verwenden.

Um die Unveränderlichkeit besser zu verstehen, lesen Sie Erics Beiträge, die mit diesem beginnen:

Unveränderlichkeit in C # Teil 1: Arten der Unveränderlichkeit


Dieses Zitat enthält eine seltsame Behauptung - dass die Stack-Datenstruktur (tatsächlich mehrere Stacks mit Tail-Sharing) insgesamt eine veränderbare Struktur ist - jeder Push oder Pop ändert die Struktur. Nur die einzelnen Artikel sind unveränderlich. Und im Prinzip könnten Sie die gleiche Struktur haben, aber mit veränderlichen Elementen. Dies geschieht in einigen Variationen von undoable Union-Find IIRC. Unveränderlichkeit hat große Vorteile, aber das Teilen eines Teils oder der gesamten Datenstruktur als Optimierung ist mit veränderlichen Elementen durchaus möglich. Selbst wenn Sie eine offensichtliche Unveränderlichkeit für andere Referenzen wünschen, können Sie diese bei Bedarf jederzeit kopieren und schreiben.
Steve314

0

Eine Möglichkeit, dieses Konzept zu verstehen, besteht darin, zu untersuchen, wie Javascript alle Objekte behandelt. Dies bedeutet, dass alle Objekte nach der Instanziierung veränderbar sind. Dies bedeutet, dass Sie ein Objekt mit neuen Methoden und Eigenschaften hinzufügen können. Dies ist wichtig, da sich das Objekt nach der Instanziierung nicht ändern kann, wenn ein Objekt unveränderlich sein soll.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.