paint-brush
Veränderliche Referenzen oder veränderliche Variablen? Rusts Mut-Mut-Mut entschlüsselnvon@charnog
904 Lesungen
904 Lesungen

Veränderliche Referenzen oder veränderliche Variablen? Rusts Mut-Mut-Mut entschlüsseln

von Denis Gonchar5m2023/09/23
Read on Terminal Reader
Read this story w/o Javascript

Zu lang; Lesen

Die Speichersicherheit von Rust beruht auf seinen Besitz- und Ausleihmechanismen. Dieser Artikel befasst sich mit den Feinheiten des Schlüsselworts mut und unterscheidet zwischen veränderlichen Referenzen und veränderlichen Variablen. Der Schlüssel zum Mitnehmen? Nicht alle Muts sind gleich: Veränderbare Referenzen ermöglichen die Änderung des Werts, auf den verwiesen wird, wohingegen veränderbare Variablen mit Referenzen die Richtung ändern können, auf die sie verweisen. Ein praktischer Visualisierungstrick mit dem =-Zeichen vereinfacht das Verständnis dieser Unterscheidungen.
featured image - Veränderliche Referenzen oder veränderliche Variablen? Rusts Mut-Mut-Mut entschlüsseln
Denis Gonchar HackerNoon profile picture

Einführung

Obwohl Rust sein Rust-Buch bereitstellt, hatte ich Schwierigkeiten, das Schlüsselwort mut zu verstehen. Ich fragte mich: „Bin ich der Einzige, der dieses Problem hat?“ Eine schnelle Google-Suche bestätigte, dass ich nicht allein war.


Aus diesem Grund habe ich beschlossen, diesen Artikel zu schreiben, um eine detaillierte Erklärung des Schlüsselworts mut zu geben. Dieser Artikel richtet sich an diejenigen, die mit Hochsprachen wie Python oder JavaScript arbeiten.

Die Variablen

Um eine unveränderliche Variable in Rust zu erstellen, schreiben Sie einfach let x = 1337 . Es ist unkompliziert. Wenn Sie eine Variable erstellen möchten, die später mutiert werden kann, fügen Sie einfach das Schlüsselwort mut nach let hinzu. Rust hat eine hilfreiche Konvention, die die Klarheit der Absichten fördert.


Durch das Hinzufügen des Schlüsselworts mut werden andere darüber informiert, dass diese Variable an einer anderen Stelle im Code geändert wird. Okay.


Lass es uns visualisieren. Zwei Variablen hier, let mut x = 1337 und let y = 42 .

Vorname; Zweiter – Typ, Dritter – Wert, Vierter – Mut-Flag.

Die Referenzen

Im Moment ist alles unkompliziert. Bei der Verwendung mut Referenzen wird es jedoch etwas komplizierter. Lassen Sie uns welche erstellen.

 let mut x = 1337; let y = 42; let x_ref = &mut x; let y_ref = &y;


Ich habe zwei Referenzen erstellt (oder im Sinne von Rust „geliehen“). Eine davon ist eine veränderbare Referenz und die andere ist eine schreibgeschützte Referenz. Lassen Sie uns dafür noch einmal ein Schema erstellen.


Im angegebenen Schema habe ich 4 Variablen, von denen 2 Referenzen sind. Beide Referenzvariablen sind unveränderlich und haben nach let nicht das Schlüsselwort mut , was bedeutet, dass ich nicht ändern kann, worauf sie verweisen. Allerdings kann ich den Wert, auf den sie verweisen, immer noch ändern.

 *x_ref = 777;


Wenn Sie dies schreiben, wird sich der Rust-Compiler nicht beschweren und der Wert von x (nicht der Verweis selbst) ändert sich in 777 . Es gibt jedoch ein rotes Quadrat im Schema, das darauf hinweist, dass x_ref die Veränderlichkeitsoption fehlt. Warum kann ich also den Wert ändern, auf den es sich bezieht?


Kommen wir zurück zum Schema für let x_ref = &mut x .


Der erste weiße Block enthält den Namen: x_ref . Der zweite informiert mich über den in dieser Variablen gespeicherten Typ. In seiner vollständigen Form, ohne implizite Typanmerkungen, kann ich wie folgt schreiben:

 let x_ref: &mut i32 = &mut x;


Ich kann das so interpretieren: Lassen Sie uns eine unveränderliche Variable namens x_ref erstellen, die einen veränderlichen Verweis auf i32 enthält, und sie sofort mit dem veränderlichen Verweis auf den i32 -Wert in der x Variablen initialisieren.


Das bedeutet, dass ich den Wert ändern kann, auf den es zeigt, aber ich kann den Wert (oder die Adresse) der Referenz nicht ändern. Mit anderen Worten, ich kann nicht so etwas schreiben wie:

 let x_ref: &mut i32 = &mut x; let mut z = 0; x_ref = &mut z; // Not allowed!


In Bezug auf die Schemata möchte ich die Richtung ändern, in die der Pfeil im obigen Codeblock zeigt. Selbst wenn die z Variable veränderbar ist, kann ich den Pfeil jedoch nicht ändern, da das Problem in der Unveränderlichkeit von x_ref selbst liegt.


Um die Pfeilrichtung zu ändern, muss ich die in der Variablen x_ref gespeicherte Adresse ändern. Dies kann ich jedoch nicht tun, da die Variable unveränderlich ist.


Lass es uns tun!

 let mut x: i32 = 1337; let mut x_ref: &mut i32 = &mut x; // I've added mut before x_ref let mut z = 0; x_ref = &mut z; // Allowed!


Es gibt hier rund um x_ref zu viele mut -Instanzen, oder? Beschreiben wir sie.


  1. let mut x_ref : Ich erstelle eine veränderbare Variable mit dem Namen x_ref , was bedeutet, dass ich ihren Wert später ändern kann.


  2. &mut i32 : Ich behaupte, dass die Variable veränderbare Verweise auf einen Wert vom Typ i32 enthalten wird.


  3. &mut x : Ich leihe mir die Variable x aus (erhalte einen Verweis darauf).


Dann habe ich eine Variable namens z erstellt und ihr den Wert 0 zugewiesen. Als ich später x_ref = &mut z schrieb, gab ich an, dass ich x_ref als eine veränderliche Variable verstehe, die nur Verweise auf i32 Werte enthalten kann.


Da der Typ von z i32 ist, kann ich seine Adresse der Variablen x_ref zuweisen. Um die Adresse von z zu erhalten, habe ich die Syntax &mut z verwendet.


Das Schema.

Der mentale Trick

Schauen Sie sich = in der Anweisung an, es sieht vielleicht etwas offensichtlich aus, aber ...

 let mut x_ref = &mut x;


… Ich sehe es als einen Teiler (besonders wenn man ihn um 90 Grad dreht), der die Aussage in zwei Unteraussagen aufteilt: links und rechts. Die linke Seite liefert Informationen über die Variable selbst, während die rechte Seite uns über den Wert informiert.


Wenn ich den Dereferenzierungsoperator * verwende, um den Wert zu ändern ...

 *x_ref = 100;

... Ich ändere den Wert der x_ref Variablen nicht. Stattdessen ändere ich den Wert, auf den x_ref verweist.

Unveränderliche Referenzen

Ich habe mut vorher häufig verwendet. Was ist, wenn ich einige davon weglasse?

 let i = 1; let j = 2; let mut k = &i;


Kann ich den Wert von i hier ändern? Mit der Divider-Technik ist die Antwort recht einfach. Ich kann den Wert von k ändern (ich sehe mut auf der linken Seite), aber der Wert (rechte Seite) ist eine unveränderliche Referenz auf i (hier gibt es kein mut ).


Daher…

 let i = 1; let j = 2; let mut k = &i; k = &j; // This is legal. *k = 3; // This is not.


Das Schema.

Abschluss

In diesem Artikel haben wir die Nuancen des Schlüsselworts mut und der Referenzen analysiert. Denken Sie daran, dass es einen Unterschied zwischen einer veränderlichen Referenz und einer veränderlichen Variablen gibt, die eine Referenz enthält. Unser Trick?


Verwenden des = -Zeichens als mentale Trennlinie, um Aufgaben in Rust besser zu verstehen. Diese einfache Visualisierung kann viele Verwirrungen beseitigen.


Viel Spaß beim Codieren!