Erstellen eines Nullvektors in Rust: Magie unter der Haube

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Nullvektor in Rust: Nicht so einfach, wie es scheint

\n\n

Was könnte einfacher sein, als einen mit Nullen gefüllten Vektor zu erstellen? In Python macht man das mit einer Zeile: [0] * n. In JavaScript — Array(n).fill(0). Aber wenn Sie zu Rust wechseln, eröffnet selbst eine so triviale Aufgabe eine ganze Welt der Systemprogrammierung, Speicherverwaltung und Zero-Cost-Abstraktionen.

\n\n

Die Frage "Creating a vector of zeros for a specific size" auf Stack Overflow hat tausende Aufrufe gesammelt. Und das ist kein Zufall: Hinter der einfachen Anfrage verbirgt sich ein tiefes Verständnis dafür, wie Rust mit Speicher, Initialisierung und Sicherheit umgeht. Heute werfen wir einen Blick unter die Haube von Rust und analysieren alle Möglichkeiten, einen Nullvektor zu erstellen, und vor allem – wir verstehen, was tatsächlich im Arbeitsspeicher passiert.

\n\n

Warum ist das schwieriger als in Python?

\n\n

In Python oder JavaScript erstellen Sie einfach ein Array, und der Interpreter erledigt die ganze Drecksarbeit für Sie. Rust hingegen ist eine systemnahe Sprache. Es erlaubt nicht, Speicher nicht initialisiert zu lassen (es sei denn, Sie verwenden unsafe). Jedes Byte muss entweder explizit gefüllt oder als "undefiniertes Verhalten" markiert sein.

\n\n

Stellen Sie sich vor: Sie bestellen 100 leere Kisten. In Python werden Ihnen einfach 100 leere Kisten geliefert. In Rust hingegen fragt der Kurier: "Was soll in jede hineingelegt werden?" – und wenn Sie es nicht sagen, kommt er einfach nicht. Dies garantiert, dass Sie nie versehentlich "Müll" aus dem Speicher lesen, der von einem vorherigen Programm übrig geblieben ist.

\n\n

Methode Nr. 1: Der Klassiker vec![0; size]

\n\n

Der offensichtlichste und empfohlene Weg ist die Verwendung des Makros vec!:

\n\n
let zeros: Vec<i32> = vec![0; 10];\nprintln!("{:?}", zeros); // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
\n\n

Kurz, elegant, verständlich. Aber was passiert unter der Haube? Lassen Sie es uns Schritt für Schritt analysieren.

\n\n

Unter der Haube von vec![0; 10]

\n\n

Wenn Sie vec![0; 10] schreiben, macht Rust Folgendes:

\n\n
    \n
  1. Speicher reservieren auf dem Heap für 10 Elemente vom Typ i32. Jeder i32 belegt 4 Bytes, insgesamt also 40 Bytes.
  2. \n
  3. Überprüfen, ob der Typ das Merkmal Clone implementiert. Zahlen i32 implementieren es, daher kann der Compiler den Wert 0 für jedes Element kopieren.
  4. \n
  5. Eine Kopierschleife starten innerhalb von alloc::vec::from_elem. Der Compiler optimiert diese Schleife zu memset (wenn der Typ ein einfacher Skalar ist).
  6. \n
  7. Ein Vec zurückgeben mit einer Länge von 10 und einer Kapazität von 10.
  8. \n
\n\n

Der entscheidende Punkt: Der Speicher bleibt nicht nicht initialisiert. Rust garantiert, dass jedes Byte mit Nullen gefüllt wird, bevor Sie Zugriff auf den Vektor erhalten.

\n\n

Methode Nr. 2: vec![Default::default(); size]

\n\n

Wenn Ihr Typ keine Zahl ist, aber das Merkmal Default implementiert, können Sie einen generischen Ansatz verwenden:

\n\n
#[derive(Default)]\nstruct Point {\n    x: f64,\n    y: f64,\n}\n\nlet points: Vec<Point> = vec![Default::default(); 5];\nprintln!("{:?}", points[0]); // Point { x: 0.0, y: 0.0 }
\n\n

Für primitive Typen liefert Default::default() 0, 0.0, false oder '\\0'. Für benutzerdefinierte Strukturen – das, was Sie in #[derive(Default)] definiert haben.

\n\n

Und wie sieht es mit der Leistung aus?

\n\n

Lassen Sie uns einen einfachen Benchmark schreiben (verwenden Sie im echten Code criterion):

\n\n
use std::time::Instant;\n\nfn main() {\n    let n = 1_000_000;\n\n    let start = Instant::now();\n    let v1 = vec![0u8; n];\n    let dur1 = start.elapsed();\n\n    let start = Instant::now();\n    let v2 = vec![0u64; n];\n    let dur2 = start.elapsed();\n\n    println!("u8:  {:?}", dur1);\n    println!("u64: {:?}", dur2);\n}
\n\n

Im

Blogs

Buchempfehlungen