Rost - Intelligente Zeiger

Rust ordnet standardmäßig alles auf dem Stapel zu. Sie können Dinge auf dem Heap speichern, indem Sie sie in intelligente Zeiger wie Box einschließen . Typen wie Vec und String helfen implizit bei der Heap-Zuordnung. Intelligente Zeiger implementieren die in der folgenden Tabelle aufgeführten Merkmale. Diese Eigenschaften der intelligenten Zeiger unterscheiden sie von einer gewöhnlichen Struktur -

Sr.Nr. Name des Merkmals Paketbeschreibung
1 Deref

std::ops::Deref

Wird für unveränderliche Dereferenzierungsvorgänge wie * v verwendet.

2 Fallen

std::ops::Drop

Wird verwendet, um Code auszuführen, wenn ein Wert den Gültigkeitsbereich verlässt. Dies wird manchmal als Destruktor bezeichnet

In diesem Kapitel lernen wir die Boxintelligenter Zeiger. Wir werden auch lernen, wie man einen benutzerdefinierten intelligenten Zeiger wie Box erstellt.

Box

Mit dem Box-Smart-Zeiger, der auch als Box bezeichnet wird, können Sie Daten auf dem Heap und nicht auf dem Stapel speichern. Der Stapel enthält den Zeiger auf die Heap-Daten. Eine Box hat keinen Leistungsaufwand, außer das Speichern ihrer Daten auf dem Heap.

Lassen Sie uns sehen, wie Sie mit einer Box einen i32-Wert auf dem Heap speichern.

fn main() {
   let var_i32 = 5; 
   //stack
   let b = Box::new(var_i32); 
   //heap
   println!("b = {}", b);
}

Ausgabe

b = 5

Verwenden Sie die Dereferenzierung, um auf einen Wert zuzugreifen, auf den eine Variable zeigt. Das * wird als Dereferenzierungsoperator verwendet. Lassen Sie uns sehen, wie die Dereferenzierung mit Box verwendet wird.

fn main() {
   let x = 5; 
   //value type variable
   let y = Box::new(x); 
   //y points to a new value 5 in the heap

   println!("{}",5==x);
   println!("{}",5==*y); 
   //dereferencing y
}

Die Variable x ist ein Werttyp mit dem Wert 5. Der Ausdruck 5 == x gibt also true zurück. Die Variable y zeigt auf den Heap. Um auf den Wert im Heap zuzugreifen, müssen wir mit * y dereferenzieren . * y gibt den Wert 5 zurück. Der Ausdruck 5 == * y gibt also true zurück.

Ausgabe

true
true

Illustration - Deref-Eigenschaft

Das Deref-Merkmal, das von der Standardbibliothek bereitgestellt wird, erfordert die Implementierung einer Methode namens deref , die sich selbst ausleiht und einen Verweis auf die inneren Daten zurückgibt. Im folgenden Beispiel wird eine Struktur MyBox erstellt , bei der es sich um einen generischen Typ handelt. Es implementiert das Merkmal Deref . Dieses Merkmal hilft uns, mit * y auf von y umschlossene Heap-Werte zuzugreifen .

use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T> { 
   // Generic structure with static method new
   fn new(x:T)-> MyBox<T> {
      MyBox(x)
   }
}
impl<T> Deref for MyBox<T> {
   type Target = T;
   fn deref(&self) -> &T {
      &self.0 //returns data
   }
}
fn main() {
   let x = 5;
   let y = MyBox::new(x); 
   // calling static method
   
   println!("5==x is {}",5==x);
   println!("5==*y is {}",5==*y); 
   // dereferencing y
   println!("x==*y is {}",x==*y);
   //dereferencing y
}

Ausgabe

5==x is true
5==*y is true
x==*y is true

Illustration - Tropfeneigenschaft

Das Drop-Merkmal enthält die drop () -Methode. Diese Methode wird aufgerufen, wenn eine Struktur, die dieses Merkmal implementiert hat, den Gültigkeitsbereich verlässt. In einigen Sprachen muss der Programmierer jedes Mal Code aufrufen, um Speicher oder Ressourcen freizugeben, wenn er eine Instanz eines intelligenten Zeigers verwendet. In Rust können Sie mithilfe der Drop-Eigenschaft eine automatische Freigabe des Speichers erreichen.

use std::ops::Deref;

struct MyBox<T>(T);
impl<T> MyBox<T> {
   fn new(x:T)->MyBox<T>{
      MyBox(x)
   }
}
impl<T> Deref for MyBox<T> {
   type Target = T;
      fn deref(&self) -< &T {
      &self.0
   }
}
impl<T> Drop for MyBox<T>{
   fn drop(&mut self){
      println!("dropping MyBox object from memory ");
   }
}
fn main() {
   let x = 50;
   MyBox::new(x);
   MyBox::new("Hello");
}

Im obigen Beispiel wird die Drop-Methode zweimal aufgerufen, wenn zwei Objekte im Heap erstellt werden.

dropping MyBox object from memory
dropping MyBox object from memory