让Rust中的盒式指针使递归类型成为可能

351 阅读3分钟

Rust Programming Language Tutorial - javatpointRust Programming Language Tutorial - javatpoint

概述

指针是一个通用的编程概念,指的是在内存中包含一个地址的变量。在Rust中,除了普通的指针之外,我们还有智能 指针智能 指针是一种数据结构,它不仅可以作为一个指针,而且还具有额外的元数据和能力。盒式 指针是Rust中智能指针的一种。

盒式指针

式指针允许你在上而不是在上存储数据。留在堆栈上的是指向 数据指针

let ptr = Box::new(25);

除了将数据存储在以外的上,Box没有任何其他功能。我们在以下情况下使用Box

  • 当你有一个在编译时无法知道大小的类型,而你想在一个需要精确大小的上下文中使用该类型的值时
  • 如果你有大量的数据,而你想转移所有权,但要确保在转移时数据不会被复制。
  • 当你想拥有一个值,而你只关心它是一个实现了特定特征的类型,而不是一个特定的类型时

使用盒子类型来存储数据

正如我们上面所讨论的,盒子 类型是用来在上而不是在上存储数据的。指向堆上数据的指针确实被存储在堆上。这里有一个例子来更好地解释它。

fn main() {
    let ptr = Box::new("hello");
    println!("The pointer points to data : {}", ptr);
}

在上面的例子中,有一个变量ptr存储了一个指向字符串 "hello "的盒子 指针。字符串 "hello "在堆上,盒子指针 **ptr**是在堆栈上。

The pointer points to data : hello

ptr变量拥有盒子指针,因此所有权的规则也适用于它。随着主方法的结束,ptr盒式指针所指向的内存将被释放,堆栈上的盒式指针也将被释放。

使用盒式指针的递归类型

在任何编程语言中,编译器需要知道任何数据类型所占用的空间。这对Rust编译器来说也是一样的,但在递归 类型的情况下,这就相当困难了。递归 类型是一种类型,其中的值可以作为自身的一部分拥有另一个相同类型的值。所以编译器不知道在编译时要为这种数据类型分配多少内存。这里有一个例子可以更好地解释它。

enum RecType {
    Cons(i32, Rectype),
    Nil,
}

这里,RecType是一个递归枚举,它有一个变体,与一个元组 *(i32,RecType)*相关。这个元组包含一个i32值和一个相同类型的值,即RecType。所以,在这种情况下,编译器在编译时为 RecType分配空间变得很困难。

为了克服这个问题,我们可以使用盒式 指针。由于我们可以在编译时知道 盒式指针所需的空间,我们可以在元组内使用一个盒式 指针,它将指向一个RecType类型的值。这里有一个例子可以更好地告诉你。

enum RecType {
    Cons(i32, Box<RecType>),
    Nil,
}

现在,这将毫无问题地进行编译。这个递归 类型可以通过下面的图来理解。

box pointersbox pointers

递归类型

现在编译器知道要为 RecType分配多少空间,因为我们知道RecType枚举中每个变量的大小。下面是我们如何使用这个RecType来递归存储数据。

use crate::RecType::{Cons, Nil};

fn main() {
    let data = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}

以上就是关于Rust中盒式指针的全部内容。