Rust默认情况下在堆栈上分配所有内容,您可以通过将它们包装在智能指针(如 Box )中来将它们存储在堆上,智能指针实现下表中列出的特征 -

Sr.No Trait name Package & 描述
1 Deref

std::ops::Deref

用于不可变的取消引用操作,如* v。

2 Drop

std::ops::Drop

当值超出范围时用于运行一些代码,有时称为析构函数

在本章中,我们将学习 Box 智能指针,我们还将学习如何创建自定义的智能指针(如Box)。

Box智能指针使您可以将数据存储在堆而不是堆栈上,堆栈包含指向堆数据的指针, Box除了将其数据存储在堆上之外,没有性能开销。

让我们看看如何使用盒子在堆上存储i32值。

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

为了访问变量所指向的值,请使用解引用。 *用作取消引用运算符,让我们看看如何对Box使用取消引用。

fn main() {
   let x=5; 
   //值类型变量
   let y=Box::new(x); 
   //y 指向堆中的新值 5

   println!("{}",5==x);
   println!("{}",5==*y); 
   //取消引用 y
}

变量x是值为5的值类型,因此,表达式 5 == x 将返回true,变量y指向堆,要访问堆中的值,我们需要使用 * y解除引用, * y 返回值5,因此,表达式 5 == * y 返回true。

true
true

Deref特性

标准库提供的Deref特性要求我们实现一种名为 deref 的方法,该方法借用 self 并返回对内部数据的引用,下面的示例创建一个结构 MyBox ,它是一种通用类型,它实现了特征 Deref ,此特征有助于我们使用 * y 访问由 y 包裹的堆值。

use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T> { 
   //具有静态方法的通用结构 new
   fn new(x:T)-> MyBox<T> {
      MyBox(x)
   }
}
impl<T> Deref for MyBox<T> {
   type Target=T;
   fn deref(&self) -> &T {
      &self.0 //返回数据
   }
}
fn main() {
   let x=5;
   let y=MyBox::new(x); 
   //调用静态方法
   
   println!("5==x is {}",5==x);
   println!("5==*y is {}",5==*y); 
   //dereferencing y
   println!("x==*y is {}",x==*y);
   //dereferencing y
}
5==x is true
5==*y is true
x==*y is true

Drop特性

Drop特性包含 drop()方法,当实现此特征的结构超出范围时,将调用此方法,在某些语言中,程序员每次使用智能指针完成操作时,都必须调用代码以释放内存或资源。在Rust中,您可以使用Drop trait实现自动内存释放。

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");
}

在上面的示例中,当我们在堆中创建两个对象 时,drop方法将被调用两次。

dropping MyBox object from memory
dropping MyBox object from memory

参考链接

https://www.learnfk.com/rust/rust-smart-pointers.html