Box, Stack und Heap

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

In diesem Lab wird das Konzept des Boxings, der Stack- und Heap-Allokation in Rust untersucht. Alle Werte in Rust werden standardmäßig auf dem Stack zugewiesen, können jedoch mit dem Typ Box<T> geboxed (auf dem Heap zugewiesen) werden. Ein Box ist ein Smart-Pointer auf einen auf dem Heap zugewiesenen Wert, und wenn er außer Reichweite gelangt, wird dessen Destruktor aufgerufen und der Speicher auf dem Heap freigegeben. Boxing ermöglicht die Erstellung von Doppelindirektion und kann mit dem *-Operator dereferenziert werden. Das Lab bietet Codebeispiele und Erklärungen dazu, wie Boxing funktioniert und wie es die Speicherzuweisung auf dem Stack beeinflusst.

Hinweis: Wenn das Lab keinen Dateinamen angibt, können Sie einen beliebigen Dateinamen verwenden. Beispielsweise können Sie main.rs verwenden und es mit rustc main.rs &&./main kompilieren und ausführen.

Box, Stack und Heap

Alle Werte in Rust werden standardmäßig auf dem Stack zugewiesen. Werte können geboxed (auf dem Heap zugewiesen) werden, indem ein Box<T> erstellt wird. Ein Box ist ein Smart-Pointer auf einen auf dem Heap zugewiesenen Wert vom Typ T. Wenn ein Box außer Reichweite gelangt, wird dessen Destruktor aufgerufen, das innere Objekt zerstört und der Speicher auf dem Heap freigegeben.

Geboxte Werte können mit dem *-Operator dereferenziert werden; dadurch wird eine Ebene der Indirektion entfernt.

use std::mem;

#[allow(dead_code)]
#[derive(Debug, Clone, Copy)]
struct Point {
    x: f64,
    y: f64,
}

// Ein Rechteck kann durch die Position seiner oberen linken und unteren rechten
// Ecken im Raum angegeben werden
#[allow(dead_code)]
struct Rectangle {
    top_left: Point,
    bottom_right: Point,
}

fn origin() -> Point {
    Point { x: 0.0, y: 0.0 }
}

fn boxed_origin() -> Box<Point> {
    // Weisen diesen Punkt auf dem Heap zu und gebe einen Zeiger darauf zurück
    Box::new(Point { x: 0.0, y: 0.0 })
}

fn main() {
    // (alle Typangaben sind überflüssig)
    // Auf dem Stack zugewiesene Variablen
    let point: Point = origin();
    let rectangle: Rectangle = Rectangle {
        top_left: origin(),
        bottom_right: Point { x: 3.0, y: -4.0 }
    };

    // Auf dem Heap zugewiesenes Rechteck
    let boxed_rectangle: Box<Rectangle> = Box::new(Rectangle {
        top_left: origin(),
        bottom_right: Point { x: 3.0, y: -4.0 },
    });

    // Die Ausgabe von Funktionen kann geboxed werden
    let boxed_point: Box<Point> = Box::new(origin());

    // Doppelindirektion
    let box_in_a_box: Box<Box<Point>> = Box::new(boxed_origin());

    println!("Point nimmt auf dem Stack {} Bytes ein",
             mem::size_of_val(&point));
    println!("Rectangle nimmt auf dem Stack {} Bytes ein",
             mem::size_of_val(&rectangle));

    // Box-Größe == Zeigergröße
    println!("Geboxter Punkt nimmt auf dem Stack {} Bytes ein",
             mem::size_of_val(&boxed_point));
    println!("Geboxtes Rechteck nimmt auf dem Stack {} Bytes ein",
             mem::size_of_val(&boxed_rectangle));
    println!("Geboxte Box nimmt auf dem Stack {} Bytes ein",
             mem::size_of_val(&box_in_a_box));

    // Kopiere die in `boxed_point` enthaltenen Daten in `unboxed_point`
    let unboxed_point: Point = *boxed_point;
    println!("Entboxter Punkt nimmt auf dem Stack {} Bytes ein",
             mem::size_of_val(&unboxed_point));
}

Zusammenfassung

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