Smart Pointer in Rust

Smart Pointer sind eine gängige Datenstruktur in Rust, die zusätzliche Funktionalität und Sicherheitsgarantien bieten, um Speicher und Daten zu verwalten.

In Rust sind Smart Pointer ein Datentyp, der die Eigentümerschaft und Lebensdauerverwaltung von dynamisch zugewiesenem Speicher kapselt.

Smart Pointer kapseln typischerweise einen Rohzeiger und bieten zusätzliche Funktionalität wie Referenzzählung, Eigentumsübertragung, Lebensdauerverwaltung usw.

In Rust bietet die Standardbibliothek mehrere gängige Smart-Pointer-Typen wie Box, Rc, Arc und RefCell.

Anwendungsfälle für Smart Pointer:

  • Wenn Sie Speicher auf dem Heap zuweisen müssen, verwenden SieBox<T>。
  • Wenn mehrere Stellen Eigentümerschaft teilen müssen, verwenden SieRc<T>oderArc<T>。
  • Wenn Sie innere Mutabilität benötigen, verwenden SieRefCell<T>。
  • Wenn Sie threadsichere gemeinsame Eigentümerschaft benötigen, verwenden SieArc<T>。
  • Wenn Sie exklusiven Zugriff auf Daten benötigen, verwenden SieMutex<T>。
  • Wenn Sie Lese-/Schreibzugriff auf Daten benötigen, verwenden SieRwLock<T>。
  • Wenn Sie Referenzzyklen auflösen müssen, verwenden SieWeak<T>。

Box<T>-Smart Pointer

Box<T> ist einer der einfachsten Smart Pointer in Rust. Er ermöglicht das Zuweisen eines Speicherblocks auf dem Heap und das Speichern eines Werts in diesem Speicher.

Aufgrund der Ownership-Regeln von Rust ermöglicht die Verwendung von Box, Daten bekannter Größe auf dem Heap zu erstellen.

Beispiel

let b = Box::new(5);
println!("b = {}", b);

Rc<T>-Smart Pointer

Rc<T> (Referenzzählungszeiger) ermöglicht mehreren Eigentümern, Daten gemeinsam zu nutzen. Er verwendet Referenzzählung, um die Anzahl der Eigentümer der Daten zu verfolgen, und gibt die Daten frei, wenn die Anzahl der Eigentümer null erreicht.

Rc<T> eignet sich für die gemeinsame Nutzung von Daten in Single-Threaded-Umgebungen.

Beispiel

use std::rc::Rc;

let data = Rc::new(5);
let data_clone = Rc::clone(&data);

Arc<T>-Smart Pointer

Arc<T> (atomarer Referenzzählungszeiger) ist ähnlich wie Rc<T>, kann aber Daten in Multithread-Umgebungen sicher gemeinsam nutzen, weil es atomare Operationen verwendet, um den Referenzzähler zu aktualisieren.

Beispiel

use std::sync::Arc;

let data = Arc::new(5);
let data_clone = Arc::clone(&data);

RefCell<T>-Smart-Pointer

RefCell<T> ermöglicht es, Borrow-Regeln zur Laufzeit zu überprüfen. Es verwendet Interior Mutability, um ein sicheres Interior-Mutability-Muster bereitzustellen, sodass Daten geändert werden können, während unveränderliche Referenzen vorhanden sind.

Allerdings kann RefCell<T> nur in Single-Thread-Umgebungen verwendet werden.

Beispiel

use std::cell::RefCell;

let data = RefCell::new(5);
let mut borrowed_data = data.borrow_mut();
*borrowed_data = 10;

Mutex<T>-Smart-Pointer

Mutex<T> ist eine Sperre für gegenseitigen Ausschluss, die garantiert, dass nur ein Thread jederzeit auf die Daten innerhalb des Mutex zugreifen kann.

Beispiel

use std::sync::Mutex;

let m = Mutex::new(5);
let mut data = m.lock().unwrap();

RwLock<T> Smart Pointer

RwLock<T> ist eine Leser-Schreib-Sperre, die mehreren Lesern gleichzeitig den Zugriff auf Daten ermöglicht, aber Schreibzugriffe sind exklusiv.

Beispiel

use std::sync::RwLock;

let lock = RwLock::new(5);
let read_guard = lock.read().unwrap();

Weak<T> Smart Pointer

Weak<T> ist ein nicht-besitzender Smart Pointer von Rc<T>. Er erhöht den Referenzzähler nicht und wird verwendet, um Probleme mit Referenzzyklen zu lösen.

Beispiel

use std::rc::{Rc, Weak};

let five = Rc::new(5);
let weak_five = Rc::downgrade(&five);

Lebensdauer-Verwaltung von Smart Pointern

Smart Pointer können dabei helfen, die Lebensdauer von Daten zu verwalten. Wenn Smart Pointer zerstört werden, geben sie automatisch Speicher frei, wodurch Speicherlecks und hängende Zeiger vermieden werden.

Darüber hinaus ermöglichen Smart Pointer die Angabe eines benutzerdefinierten Destruktors zum Zeitpunkt der Erstellung, um eine benutzerdefinierte Ressourcenverwaltung zu erreichen.

Beispiel

Im Folgenden finden Sie ein vollständiges Beispiel für einen einfachen Rust-Smart-Pointer. Dieses Beispiel verwendet den Rc<T>-Smart-Pointer, um eine einfache Referenzzählung zu implementieren, und demonstriert mehrere Eigentümer, die Daten gemeinsam nutzen.

Beispiel

// Erforderliche Abhängigkeiten importieren
use std::rc::Rc;

// Definiere eine Struktur zum Speichern von Daten
#[derive(Debug)]
struct Data {
    value: i32,
}

// Hauptfunktion
fn main() {
    // Erstelle einen Rc-Smart-Pointer, um Daten gemeinsam zu nutzen
    let data = Rc::new(Data { value: 5 });

    // Klone den Rc-Smart-Pointer, um den Referenzzähler der Daten zu erhöhen
    let data_clone1 = Rc::clone(&data);
    let data_clone2 = Rc::clone(&data);

    // Wert und Referenzanzahl der Daten ausgeben
    println!("Datenwert: {}", data.value);
    println!("Referenzanzahl: {}", Rc::strong_count(&data));

    // Den geklonten Rc-Smart-Pointer ausgeben
    println!("Datenklon 1: {:?}", data_clone1);
    println!("Datenklon 2: {:?}", data_clone2);
}

Im obigen Code definieren wir zunächst einDatastruct zum Speichern eines Ganzzahlwerts. Dann in dermainFunktion haben wir einenRc<Data>Smart Pointer zum Teilen von Daten erstellt. Dann mit derRc::cloneMethode haben wir zwei Smart Pointer geklont, wodurch die Referenzanzahl der Daten erhöht wurde. Schließlich haben wir den Wert der Daten, die Referenzanzahl und die geklonten Smart Pointer ausgegeben.

Wenn Sie das Programm ausführen, können Sie sehen, dass es den Wert und die Referenzanzahl der Daten sowie die geklonten Smart Pointer ausgibt. DaRcSmart Pointer die Referenzzählung verwenden, um die Anzahl der Besitzer der Daten zu verfolgen, sodass bei jedem Klonen die Referenzanzahl der Daten steigt und die Daten automatisch freigegeben werden, wenn die Anzahl der Besitzer null erreicht.

Die Ausgabe sieht wie folgt aus:

Data value: 5
Reference count: 3
Data clone 1: Data { value: 5 }
Data clone 2: Data { value: 5 }

Zusammenfassung

Die Smart Pointer von Rust bieten eine sichere und automatische Möglichkeit, Speicher und Eigentümerschaft zu verwalten.

Smart Pointer sind eine sehr wichtige Datenstruktur in Rust. Sie bieten eine sichere, flexible und bequeme Möglichkeit, Speicher zu verwalten, häufige Probleme mit der Speichersicherheit zu vermeiden und die Zuverlässigkeit und Wartbarkeit von Code zu verbessern.

Smart Pointer sind ein wichtiger Teil des Sicherheitsmodells und ermöglichen Entwicklern, Low-Level-Code zu schreiben, ohne sich um Speichersicherheit sorgen zu müssen.

Durch Smart Pointer behält Rust die Kontrolle von C bei und vermeidet dabei die damit verbundenen Risiken.

Andere Erweiterungen