Variablen und Veränderbarkeit

RustRustBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Willkommen zu Variablen und Veränderbarkeit. Dieser Lab ist ein Teil des Rust Buches. Du kannst deine Rust-Fähigkeiten in LabEx üben.

In diesem Lab befassen wir uns mit dem Konzept der Veränderbarkeit in Rust, diskutieren, wie Variablen standardmäßig unveränderlich sind und wie man sie mit dem Schlüsselwort mut veränderbar macht, und betonen die Wichtigkeit der Unveränderbarkeit für Sicherheit und Parallelität, während wir gleichzeitig die Nützlichkeit der Veränderbarkeit in bestimmten Situationen anerkennen.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/mutable_variables("Mutable Variables") rust/BasicConceptsGroup -.-> rust/constants_usage("Constants Usage") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") subgraph Lab Skills rust/variable_declarations -.-> lab-100387{{"Variablen und Veränderbarkeit"}} rust/mutable_variables -.-> lab-100387{{"Variablen und Veränderbarkeit"}} rust/constants_usage -.-> lab-100387{{"Variablen und Veränderbarkeit"}} rust/integer_types -.-> lab-100387{{"Variablen und Veränderbarkeit"}} rust/function_syntax -.-> lab-100387{{"Variablen und Veränderbarkeit"}} rust/expressions_statements -.-> lab-100387{{"Variablen und Veränderbarkeit"}} rust/method_syntax -.-> lab-100387{{"Variablen und Veränderbarkeit"}} end

Variablen und Veränderbarkeit

Wie in "Speichern von Werten mit Variablen" erwähnt, sind Variablen standardmäßig unveränderlich. Dies ist einer der vielen Hinweise, die Rust Ihnen gibt, um Ihren Code so zu schreiben, dass Sie die Sicherheit und die einfache Parallelität nutzen, die Rust bietet. Dennoch haben Sie die Option, Ihre Variablen veränderbar zu machen. Lassen Sie uns untersuchen, wie und warum Rust Sie ermutigt, die Unveränderbarkeit zu bevorzugen und warum Sie manchmal abweichen möchten.

Wenn eine Variable unveränderlich ist, können Sie den Wert, der an einen Namen gebunden ist, nicht mehr ändern, nachdem er einmal zugewiesen wurde. Um dies zu veranschaulichen, erstellen Sie ein neues Projekt namens variables im project-Verzeichnis, indem Sie cargo new variables verwenden.

Öffnen Sie dann in Ihrem neuen variables-Verzeichnis src/main.rs und ersetzen Sie seinen Code durch folgenden Code, der noch nicht kompilieren wird:

Dateiname: src/main.rs

fn main() {
    let x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}

Speichern Sie die Datei und führen Sie das Programm mit cargo run aus. Sie sollten eine Fehlermeldung über einen Unveränderbarkeitsfehler erhalten, wie in dieser Ausgabe zu sehen:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         -
  |         |
  |         first assignment to `x`
  |         help: consider making this binding mutable: `mut x`
3 |     println!("The value of x is: {x}");
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

Dieses Beispiel zeigt, wie der Compiler Ihnen hilft, Fehler in Ihrem Programm zu finden. Compilerfehler können frustrierend sein, aber im Grunde bedeuten sie nur, dass Ihr Programm noch nicht sicher macht, was Sie es tun möchten; sie bedeuten nicht, dass Sie kein guter Programmierer sind! Erfahrungene Rust-Entwickler erhalten immer noch Compilerfehler.

Sie haben die Fehlermeldung cannot assign twice to immutable variablex`erhalten, weil Sie versucht haben, einen zweiten Wert an die unveränderliche Variablex` zuzuweisen.

Es ist wichtig, dass wir Kompilierungsfehler erhalten, wenn wir versuchen, einen Wert zu ändern, der als unveränderlich markiert ist, da genau diese Situation zu Fehlern führen kann. Wenn ein Teil unseres Codes davon ausgeht, dass ein Wert sich niemals ändert und ein anderer Teil unseres Codes diesen Wert ändert, ist es möglich, dass der erste Teil des Codes nicht mehr das tut, was er ursprünglich getan haben soll. Der Grund für einen solchen Fehler kann sich nachträglich schwer verfolgen lassen, insbesondere wenn der zweite Codeabschnitt den Wert nur manchmal ändert. Der Rust-Compiler garantiert, dass, wenn Sie angeben, dass ein Wert sich nicht ändern wird, er tatsächlich nicht ändern wird, so dass Sie sich nicht selbst darum kümmern müssen. Ihr Code ist daher einfacher zu verstehen.

Aber Veränderbarkeit kann sehr nützlich sein und das Schreiben von Code einfacher machen. Obwohl Variablen standardmäßig unveränderlich sind, können Sie sie veränderbar machen, indem Sie mut vor dem Variablennamen hinzufügen, wie Sie es im zweiten Kapitel getan haben. Das Hinzufügen von mut gibt auch der späteren Leserschaft des Codes die Absicht an, indem es angibt, dass andere Teile des Codes diesen Variablenwert ändern werden.

Beispielsweise ändern wir src/main.rs wie folgt:

Dateiname: src/main.rs

fn main() {
    let mut x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}

Wenn wir das Programm jetzt ausführen, erhalten wir Folgendes:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.30s
     Running `target/debug/variables`
The value of x is: 5
The value of x is: 6

Wir dürfen den an x gebundenen Wert von 5 auf 6 ändern, wenn mut verwendet wird. Letztendlich ist es Ihnen überlassen, ob Sie Veränderbarkeit verwenden oder nicht, und dies hängt davon ab, was Ihnen in dieser speziellen Situation am klarsten erscheint.

Konstanten

Ähnlich wie unveränderliche Variablen sind Konstanten Werte, die an einen Namen gebunden sind und nicht geändert werden dürfen, aber es gibt einige Unterschiede zwischen Konstanten und Variablen.

Zunächst ist es nicht möglich, mut mit Konstanten zu verwenden. Konstanten sind nicht nur standardmäßig unveränderlich - sie sind immer unveränderlich. Sie deklarieren Konstanten mit dem Schlüsselwort const anstelle des let-Schlüsselworts, und der Typ des Werts muss annotiert werden. Wir werden in "Datentypen" auf Typen und Typannotationen eingehen, also brauchen Sie sich jetzt nicht um die Details zu kümmern. Einfach wissen, dass Sie immer den Typ annotieren müssen.

Konstanten können in jedem Gültigkeitsbereich deklariert werden, einschließlich des globalen Gültigkeitsbereichs, was sie für Werte nützlich macht, über die viele Teile des Codes informiert sein müssen.

Der letzte Unterschied ist, dass Konstanten nur einem Konstantenausdruck zugewiesen werden können, nicht dem Ergebnis eines Werts, der nur zur Laufzeit berechnet werden kann.

Hier ist ein Beispiel für eine Konstantendeklaration:

const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

Der Name der Konstante ist THREE_HOURS_IN_SECONDS und ihr Wert ist auf das Ergebnis der Multiplikation von 60 (der Anzahl der Sekunden in einer Minute) mit 60 (der Anzahl der Minuten in einer Stunde) mit 3 (der Anzahl der Stunden, die wir in diesem Programm zählen möchten) gesetzt. Rusts Namenskonvention für Konstanten ist, alle Großbuchstaben zu verwenden und Unterstriche zwischen den Wörtern. Der Compiler kann eine begrenzte Anzahl von Operationen zur Compile-Zeit auswerten, was uns ermöglicht, diesen Wert auf eine Weise zu schreiben, die einfacher zu verstehen und zu verifizieren ist, anstatt diese Konstante auf den Wert 10.800 zu setzen. Weitere Informationen über die Operationen, die bei der Deklaration von Konstanten verwendet werden können, finden Sie im Abschnitt zur Konstantenauswertung in der Rust-Referenz unter https://doc.rust-lang.org/reference/const_eval.html.

Konstanten sind für die gesamte Laufzeit eines Programms gültig, innerhalb des Gültigkeitsbereichs, in dem sie deklariert wurden. Diese Eigenschaft macht Konstanten nützlich für Werte in Ihrem Anwendungsbereich, über die mehrere Teile des Programms informiert sein müssen, wie die maximale Anzahl von Punkten, die ein Spieler eines Spiels erreichen darf, oder die Lichtgeschwindigkeit.

Das Benennen von hartcodierten Werten, die im gesamten Programm verwendet werden, als Konstanten ist hilfreich, um die Bedeutung dieses Werts für zukünftige Wartende des Codes zu vermitteln. Es hilft auch, nur einen einzigen Ort im Code zu haben, an dem Sie ändern müssen, wenn der hartcodierte Wert in Zukunft aktualisiert werden muss.

Shadowing

Wie Sie im Tippspiel-Tutorial im zweiten Kapitel gesehen haben, können Sie eine neue Variable mit dem gleichen Namen wie eine vorherige Variable deklarieren. Rust-Entwickler sagen, dass die erste Variable von der zweiten verdeckt wird, was bedeutet, dass die zweite Variable das ist, was der Compiler sieht, wenn Sie den Variablennamen verwenden. In der Tat überdeckt die zweite Variable die erste, indem sie alle Verwendung des Variablennamens auf sich zieht, bis entweder sie selbst verdeckt wird oder der Gültigkeitsbereich endet. Wir können eine Variable verbergen, indem wir denselben Variablennamen verwenden und die Verwendung des let-Schlüsselworts wiederholen, wie folgt:

Dateiname: src/main.rs

fn main() {
    let x = 5;

    let x = x + 1;

    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x}");
    }

    println!("The value of x is: {x}");
}

Dieses Programm bindet zunächst x an einen Wert von 5. Anschließend erstellt es eine neue Variable x, indem es let x = wiederholt, nimmt den ursprünglichen Wert und addiert 1, sodass der Wert von x dann 6 ist. Anschließend, innerhalb eines inneren Gültigkeitsbereichs, der mit geschweiften Klammern erstellt wird, deklariert der dritte let-Befehl ebenfalls x und erstellt eine neue Variable, indem er den vorherigen Wert mit 2 multipliziert, um x einen Wert von 12 zu geben. Wenn dieser Gültigkeitsbereich vorbei ist, endet das innere Verbergen und x kehrt wieder auf 6 zurück. Wenn wir dieses Programm ausführen, wird es folgendes ausgeben:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s
     Running `target/debug/variables`
The value of x in the inner scope is: 12
The value of x is: 6

Das Verbergen unterscheidet sich von der Markierung einer Variable als mut, weil wir einen Compile-Zeitfehler erhalten, wenn wir versehentlich versuchen, dieser Variable erneut zuzuweisen, ohne das let-Schlüsselwort zu verwenden. Indem wir let verwenden, können wir einige Transformationen an einem Wert vornehmen, aber die Variable bleibt unveränderlich, nachdem diese Transformationen abgeschlossen sind.

Der andere Unterschied zwischen mut und Verbergen besteht darin, dass wir effektiv eine neue Variable erstellen, wenn wir das let-Schlüsselwort erneut verwenden, sodass wir den Typ des Werts ändern können, aber den gleichen Namen wiederverwenden können. Beispielsweise sagen wir, dass unser Programm einen Benutzer auffordert, anzugeben, wie viele Leerzeichen sie zwischen einigen Texten möchten, indem sie Leerzeichen eingeben, und wir möchten diese Eingabe als Zahl speichern:

let spaces = "   ";
let spaces = spaces.len();

Die erste spaces-Variable ist vom String-Typ und die zweite spaces-Variable ist vom Zahlentyp. Das Verbergen erspart uns daher die Notwendigkeit, verschiedene Namen wie spaces_str und spaces_num zu erfinden; anstatt dessen können wir den einfachereren Namen spaces wiederverwenden. Wenn wir jedoch versuchen, mut für dies zu verwenden, wie hier gezeigt, erhalten wir einen Compile-Zeitfehler:

let mut spaces = "   ";
spaces = spaces.len();

Der Fehler besagt, dass wir nicht zulassen, den Typ einer Variable zu mutieren:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
 --> src/main.rs:3:14
  |
2 |     let mut spaces = "   ";
  |                      ----- expected due to this value
3 |     spaces = spaces.len();
  |              ^^^^^^^^^^^^ expected `&str`, found `usize`

Jetzt, nachdem wir untersucht haben, wie Variablen funktionieren, schauen wir uns an, welche weiteren Datentypen sie haben können.

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Lab zu Variablen und Veränderbarkeit abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.