Einführung
Rust verwendet String für eigenen, erweiterbaren Text und &str für eine geliehene Ansicht auf Text. Ein String-Slice kann einen vollständigen String oder einen ausgewählten Bytebereich anzeigen, ohne die Zeichen zu kopieren.
Sie übergeben eigenen Text an eine Funktion, die &str leiht, erstellen ein geliehenes Befehlsstichwort und fordern den Compiler absichtlich dazu auf, UTF-8-Text auf nicht unterstützte Weise zu indizieren. Anschließend korrigieren Sie den Code mit einem gültigen Slice, das die Grenzen berücksichtigt.
Eigenen und literalen Text als &str ausleihen
In diesem Schritt übergeben Sie zwei verschiedene Textquellen an eine Funktion, die einen geliehenen String-Slice akzeptiert.
Wechseln Sie in das vorbereitete Projekt und öffnen Sie den Quellcode:
cd /home/labex/project/string-slices
nano src/main.rs
Der Typ String besitzt erweiterbaren Text. Der Typ &str, ausgesprochen „String-Slice“, ist eine geliehene Ansicht auf gültigen UTF-8-Text. Ein Stringliteral wie "preview" hat bereits den geliehenen String-Slice-Typ, weil das Programm seinen Text während der gesamten Laufzeit speichert.
Die Funktion show_text(label: &str) kann beide Textarten anzeigen. Ersetzen Sie nur /* Step 1: borrow command */ durch &command:
show_text(&command);
Rust behandelt das geliehene &String automatisch als die &str-Ansicht, die die Funktion erwartet. Bei dieser Umwandlung werden die Zeichen weder kopiert noch verschoben.
Speichern Sie mit Ctrl+O, drücken Sie Enter und beenden Sie den Editor mit Ctrl+X. Führen Sie anschließend das Programm aus:
cargo run --quiet
Die Ausgabe sollte wie folgt aussehen:
Text: serve reports
Text: preview
Keyword: <>
Status: ✅ ready
Beide Aufrufe erreichen denselben &str-Parameter. Das leere Stichwort ist ein vorbereiteter Platzhalter für den nächsten Schritt.
Einen Teilstring ausleihen, ohne ihn zu kopieren
In diesem Schritt lassen Sie keyword nur das Präfix serve innerhalb von command anzeigen.
Öffnen Sie den Quellcode:
nano src/main.rs
Die Slice-Form &text[start..end] leiht einen Bereich aus. Der Startpunkt ist eingeschlossen, der Endpunkt ausgeschlossen. Rust zählt bei String-Bereichen Bytes. Die ASCII-Buchstaben in serve belegen jeweils ein Byte. Deshalb beginnt der Bereich bei Byte 0 und endet vor Byte 5.
Ersetzen Sie nur das leere Literal "" in der Zeile für Schritt 2 durch &command[0..5]:
let keyword = &command[0..5]; // Step 2: replace the empty slice.
Das resultierende &str zeigt in command; es reserviert keinen Speicher und kopiert keinen zweiten String. Da command weiterhin im Gültigkeitsbereich liegt, bleibt die geliehene Ansicht gültig, solange Sie keyword verwenden.
Speichern und beenden Sie den Editor. Führen Sie anschließend den Code aus:
cargo run --quiet
Die letzte Zeile sollte nun lauten:
Keyword: <serve>
Der eigene command enthält weiterhin den vollständigen Text serve reports, während keyword nur ein geliehenes Fenster auf die ersten fünf Bytes ist.
UTF-8-Zeichengrenzen beachten
In diesem Schritt versuchen Sie absichtlich, eine Ganzzahl-Indizierung zu verwenden, lesen die Erklärung des Compilers und ersetzen sie durch einen gültigen UTF-8-Slice.
UTF-8-Zeichen belegen nicht alle gleich viele Bytes. In "✅ ready" verwendet das Häkchen drei Bytes. Deshalb ist Byte null nicht automatisch „das erste Zeichen“, und Rust erlaubt status[0] für einen String nicht.
Öffnen Sie die Datei und entfernen Sie nur die führenden // aus der Ausgabezeile für Schritt 3:
nano src/main.rs
Speichern und beenden Sie den Editor. Führen Sie anschließend die Überprüfung aus. Ein Fehler ist an dieser Stelle zu erwarten:
cargo check
Suchen Sie nach dieser unveränderten Meldung:
error[E0277]: the type `str` cannot be indexed by `{integer}`
Diese Diagnose verhindert, dass Sie so tun, als hätte jedes Zeichen eine Position von genau einem Byte. Öffnen Sie die Datei erneut und ersetzen Sie die fehlerhafte Ausgabezeile durch diese beiden kurzen Zeilen:
let symbol = &status[0..3];
println!("Status symbol: {symbol}");
Der Bereich 0..3 endet genau hinter dem drei Byte langen Symbol. Das funktioniert, weil der vorbereitete Text und seine Byte-Grenze im Voraus bekannt sind. Es ist keine allgemeine Methode, um das erste für Menschen sichtbare Zeichen eines beliebigen Textes zu finden. Ein Bereich, der mitten durch ein UTF-8-Zeichen verläuft, würde zur Laufzeit einen Panic auslösen. String-Bereiche müssen daher an bekannten gültigen Grenzen beginnen und enden.
Speichern und beenden Sie den Editor. Überprüfen und starten Sie den Code anschließend:
cargo check
cargo run --quiet
Die vollständige Ausgabe sollte wie folgt aussehen:
Text: serve reports
Text: preview
Keyword: <serve>
Status: ✅ ready
Status symbol: ✅
Die erfolgreiche Ausgabe bestätigt, dass das abschließende Slice ein vollständiges UTF-8-Zeichen auswählt, ohne den ursprünglichen String zu kopieren.
Zusammenfassung
Sie haben eigene String-Werte mit geliehenen &str-Ansichten verbunden, einen Teilstring ohne Speicherreservierung ausgewählt und gelernt, warum UTF-8-Text nicht wie ein zeichenweises Byte-Array behandelt werden kann. Sichere String-Bereiche müssen an gültigen UTF-8-Grenzen beginnen und enden.


