Vec<T>-Slices in Rust: Wie funktionieren sie und warum braucht man sie?
\n\nWenn Sie jemals in Rust programmiert und sich gefragt haben "How do I get a slice of a Vec<T> in Rust?" – sind Sie nicht allein. Dies ist eine der beliebtesten Fragen auf Stack Overflow mit tausenden von Aufrufen. Und das aus gutem Grund: Die Arbeit mit Vektoren und ihren Slices ist eine grundlegende Fähigkeit, ohne die man sich kein ernsthaftes Rust-Projekt vorstellen kann.
\n\nIn diesem Artikel zeigen wir nicht nur, wie man einen Slice erstellt. Wir behandeln die Best Practices für 2025, lernen, typische Fallstricke zu vermeiden, und verstehen, warum Rust uns überhaupt so viel über Ausleihen nachdenken lässt. Los geht's!
\n\nWas ist ein Slice in Rust?
\n\nBevor wir einen Slice erstellen, lassen Sie uns klären, was das ist. Ein Slice ist ein Verweis auf eine zusammenhängende Sequenz von Elementen im Speicher. In Rust wird ein Slice als &[T] bezeichnet. Es ist keine besitzende Datenstruktur – es "blickt" lediglich auf einen Teil der Daten, die jemand anderem gehören (z. B. einem Vektor oder Array).
Der Hauptvorteil von Slices ist die Sicherheit. Der Rust-Compiler garantiert, dass Sie nicht über die Speichergrenzen hinausgehen, und das Ausleihsystem verhindert, dass Sie Daten ändern, während aktive Verweise darauf existieren.
\n\nWarum nicht direkt den Vektor verwenden?
\n\nEin Vektor (Vec<T>) ist eine besitzende Struktur. Wenn Sie ihn an eine Funktion übergeben, verschieben Sie ihn (verlieren den Zugriff) oder übergeben einen Verweis. Slices bieten Ihnen Flexibilität: Sie können nur einen Teil der Daten übergeben, ohne sie zu kopieren oder die Kontrolle über den ursprünglichen Vektor zu verlieren.
Angenommen, Sie arbeiten mit einem großen Datenarray und möchten einen Ausschnitt davon zur Analyse an eine Funktion übergeben. Ein Slice ist das ideale Werkzeug: Er ist leichtgewichtig (nur zwei Wörter: Zeiger und Länge) und sicher.
\n\nHauptmethoden zum Erstellen eines Vec<T>-Slices
\n\nKommen wir zur Praxis. Es gibt mehrere Möglichkeiten, einen Slice aus einem Vektor zu erstellen. Wir betrachten die gängigsten und bequemsten.
\n\n1. Der Indexierungsoperator: &vec[start..end]
\n\nDer direkteste Weg ist die Verwendung des Bereichsoperators ..:
let vec = vec![1, 2, 3, 4, 5];\nlet slice: &[i32] = &vec[1..4]; // Slice von Index 1 bis 4 (exklusive 4)\nprintln!("{:?}", slice); // [2, 3, 4]\n\nDiese Methode verwendet eine Laufzeit-Grenzprüfung. Wenn Sie die Grenzen des Vektors überschreiten, gerät das Programm in Panik (panic). Für Übungsbeispiele ist das in Ordnung, aber im Produktionscode sollte man vorsichtig sein.
\n\nSie können verschiedene Formen von Bereichen verwenden:
\n\n- \n
&vec[..]– der gesamte Vektor \n&vec[2..]– ab Index 2 bis zum Ende \n&vec[..3]– vom Anfang bis Index 3 (exklusive) \n&vec[1..=3]– von 1 bis einschließlich 3 \n
2. Die Methode .as_slice()
\n\nDiese Methode gibt einen Slice auf den gesamten Vektor zurück. Sie ist sicherer als &vec[..], da sie die Absicht explizit ausdrückt:
let vec = vec![10, 20, 30];\nlet slice: &[i32] = vec.as_slice();\nprintln!("{:?}", slice); // [10, 20, 30]\n\nDie Methode as_slice() ist besonders nützlich, wenn Sie betonen möchten, dass Sie mit einem Slice und nicht mit einem Vektor arbeiten. Dies macht den Code lesbarer und selbstdokumentierend.
3. Erstellen eines veränderlichen Slices: as_mut_slice()
\n\nWenn Sie die Elemente innerhalb des Slices (aber nicht den Vektor selbst) ändern müssen, verwenden Sie as_mut_slice():
let mut vec = vec![1, 2, 3];\nlet slice: &mut [i32] = vec.as_mut_slice();\nslice[0] = 100;\nprintln!("{:?}", vec); // [100, 2, 3]\n\nBeachten Sie: Der Vektor muss als mut deklariert sein. Außerdem können Sie nicht gleichzeitig einen unveränderlichen und einen veränderlichen Slice haben – dies würde die Ausleihregeln verletzen.