当前位置: 首页 > wzjs >正文

网站建设的环境深圳建筑公司排名前二十

网站建设的环境,深圳建筑公司排名前二十,手机照片制作成相册,高校微信网站建设情况汇报Rust 学习笔记&#xff1a;Box< T > Rust 学习笔记&#xff1a;Box<T\>Box\<T> 简介使用 Box\<T\> 在堆上存储数据启用带有 box 的递归类型关于 cons 列表的介绍计算非递归类型的大小使用 Box\<T\> 获取大小已知的递归类型 Rust 学习笔记&#x…

Rust 学习笔记:Box< T >

  • Rust 学习笔记:Box<T\>
    • Box\<T> 简介
    • 使用 Box\<T\> 在堆上存储数据
    • 启用带有 box 的递归类型
      • 关于 cons 列表的介绍
      • 计算非递归类型的大小
      • 使用 Box\<T\> 获取大小已知的递归类型

Rust 学习笔记:Box<T>

指针是在内存中包含地址的变量的一般概念。这个地址引用或“指向”其他一些数据。在 Rust 中最常见的指针类型是引用,由 & 符号表示,并借用它们所指向的值。除了引用数据之外,它们没有任何特殊功能,也没有开销。

智能指针是一种像指针一样的数据结构,但还具有额外的元数据和功能。Rust 在标准库中定义了各种智能指针,这些指针提供的功能超出了引用所提供的功能。

具有所有权和借用概念的 Rust 在引用和智能指针之间有一个额外的区别:引用只借用数据,而在许多情况下,智能指针拥有它们所指向的数据。

我们遇到了一些智能指针:String 和 Vec<T>。这两种类型都算作智能指针,因为它们拥有一些内存,并允许对其进行操作。它们还具有元数据和额外的功能或保证。例如,String 将其容量存储为元数据,并具有确保其数据始终是有效的 UTF-8 的额外能力。

智能指针通常使用结构体实现。与普通结构体不同,智能指针实现了 Deref 和Drop trait。Deref trait 允许智能指针结构体的实例表现得像引用一样,这样就可以编写代码来使用引用或智能指针。Drop trait 允许自定义当智能指针的实例超出作用域时运行的代码。

Box<T> 简介

最直接的智能指针是 Box<T>,它运行将数据存储在堆中而不是栈中,留在栈上的是指向堆数据的指针。

Box<T> 没有性能开销,但它们也没有太多额外的功能。最常在以下情况下使用它:

  • 当你的类型在编译时无法知道其大小,并且你希望在需要精确大小的上下文中使用该类型的值时

  • 当你有大量的数据,你想要转移所有权,但要确保数据不会被复制时

  • 当你想拥有一个值,你只关心它是一个实现了特定特性的类型,而不是一个特定的类型

我们将在下文中演示第一种情况。在第二种情况下,传输大量数据的所有权可能需要很长时间,因为数据是在栈上复制的。为了在这种情况下提高性能,我们可以将大量数据存储在堆中的盒子中。然后,只有少量的指针数据在栈上被复制,而它引用的数据留在堆上的一个地方。第三种情况被称为 trait 对象,后续文章将专门讨论了这个主题。

使用 Box<T> 在堆上存储数据

首先介绍 Box<T> 的语法以及如何与存储在 Box<T> 中的值进行交互。

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

我们将变量 b 定义为具有指向值 5 的 box 的值,该值在堆上分配。这个程序将输出 b = 5。在这种情况下,我们可以访问 box 中的数据,就像我们访问栈中的数据一样。

当一个 box 超出作用域时,就像 main 语句末尾的 b 变量那样,它将被释放。对 box(存储在栈上)和它所指向的数据(存储在堆上)都进行释放。

将单个值放在堆上并不是很有用,在栈上使用单个 i32 这样的值更合适。

Box<T> 在定义类型时更有用。

启用带有 box 的递归类型

递归类型的值可以有另一个相同类型的值作为其本身的一部分。递归类型造成了一个问题,因为 Rust 需要在编译时知道一个类型占用了多少空间。然而,递归类型的值的嵌套理论上可以无限地继续下去,因此 Rust 无法知道值需要多少空间。因为 box 的大小是已知的,所以我们可以通过在递归类型定义中插入一个 box 来启用递归类型。

作为递归类型的一个示例,让我们研究一下 cons 列表。这是函数式编程语言中常见的一种数据类型。

关于 cons 列表的介绍

cons 列表是一种来自 Lisp 编程语言的数据结构,由嵌套对组成,是 Lisp 版本的链表。它的名字来自于 Lisp 中的c ons 函数(construct function 的缩写),它从它的两个参数构造一个新的 pair。通过对由一个值和另一个值组成的对调用 cons,我们可以构造由递归对组成的 cons 列表。

例如,下面是一个 cons 列表的伪代码表示,其中包含列表 1、2、3,每一对都在括号中:

(1, (2, (3, Nil)))

cons 列表中的每一项包含两个元素:当前项的值和下一项的值。列表中的最后一项只包含一个名为 Nil 的值,没有下一项。

cons 列表不是Rust中常用的数据结构。但从本章的 cons 列表开始,我们可以探索 box 如何让我们定义递归数据类型。

下列代码包含了 cons 列表的枚举定义。

enum List {Cons(i32, List),Nil,
}

注意,这段代码还不能编译,因为 List 类型没有已知的大小,我们将对此进行演示。

尝试构建一个 cons 列表:

use crate::List::{Cons, Nil};fn main() {let list = Cons(1, Cons(2, Cons(3, Nil)));
}

第一个 Cons 值保存 1 和另一个 List 值。这个 List 值是另一个 Cons 值,它包含 2 和另一 List 值。这个 List 值是另一个 Cons 值,它包含 3 和一个 List 值,最后是 Nil,这是表示列表结束的非递归变体。

尝试运行这段代码,报错:

在这里插入图片描述

错误显示 List 类型“具有无限大小”。原因是我们用递归的变量定义了 List:它直接保存自身的另一个值。因此,Rust 无法计算出它需要多少空间来存储 List 值。

让我们分析一下为什么会出现这个错误。首先,我们来看一下 Rust 如何决定存储非递归类型的值需要多少空间。

计算非递归类型的大小

以一个 Message 枚举为例:

enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(i32, i32, i32),
}

为了确定为 Message 值分配多少空间,Rust 遍历每个变体,以查看哪个变体需要最多的空间。Message::Quit 不需要任何空间,Message::Move 占用两个 i32 值大小的空间,以此类推。因为只使用一个变体,所以 Message 值所需的最大空间就是存储其最大变体所需的空间。

与此形成对比的是,当 Rust 试图确定 List 枚举这样的递归类型需要多少空间时发生的情况。编译器首先查看 Cons 变量,它包含一个 i32 类型的值和一个 List 类型的值。因此,Cons 需要的空间量等于 i32 的大小加上 List 的大小。为了计算出 List 类型需要多少内存,编译器从 Cons 变量开始,这个过程无限地继续下去。

在这里插入图片描述

使用 Box<T> 获取大小已知的递归类型

因为 Rust 不能计算出为递归定义的类型分配多少空间,编译器给出了一个错误,并给出了这个有用的建议:

在这里插入图片描述

在这个建议中,间接意味着不是直接存储一个值,而是通过存储指向该值的指针来改变数据结构,从而间接存储该值。

因为 Box<T> 是一个指针,指针的大小不会根据它所指向的数据量而改变。这意味着我们可以在 Cons 变量中放入 Box<T>,而不是直接放入另一个 List 值。Box<T> 将指向下一个 List 值,该值将位于堆上,而不是在 Cons 变量中。

从概念上讲,我们仍然有一个列表,创建了包含其他列表的列表。但是这个实现现在更像是将项放在另一个项旁边,而不是放在另一个项内部。

修改代码:

enum List {Cons(i32, Box<List>),Nil,
}use crate::List::{Cons, Nil};fn main() {let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}

一个 Cons 变量 = 一个 i32 + 一个Box<T> 指针。Nil 不存储任何值,因此它比 Cons 变量需要更少的空间。通过使用盒子,我们打破了无限的递归链,因此编译器可以计算出存储 List 值所需的大小。

在这里插入图片描述

盒子只提供间接分配和堆分配,没有任何其他特殊功能,也没有这些特殊功能所带来的性能开销,因此它们在像 cons 列表这样的情况下非常有用,其中间接是我们唯一需要的特性。

Box<T> 类型是一个智能指针,因为它实现了 Deref trait,它允许 Box<T> 值被当作引用来对待。当 Box<T> 值超出作用域时,由于 Drop trait 的实现,该指针所指向的堆数据也会被清理。


文章转载自:

http://hWJmscz1.tpnch.cn
http://8hAmztiW.tpnch.cn
http://AyVkBGzI.tpnch.cn
http://3AI5aBOx.tpnch.cn
http://PXyPs2G1.tpnch.cn
http://WpHZGys8.tpnch.cn
http://tb30oryB.tpnch.cn
http://o7BkrBpb.tpnch.cn
http://8j4EfT6p.tpnch.cn
http://PWkkZSar.tpnch.cn
http://65jvpM4V.tpnch.cn
http://Mq5uRt2p.tpnch.cn
http://Le2pj1TD.tpnch.cn
http://mplUsKtN.tpnch.cn
http://rgZB7K5U.tpnch.cn
http://BVabgTdB.tpnch.cn
http://CoVCZJ9b.tpnch.cn
http://xTbjbvXY.tpnch.cn
http://ts9gdD41.tpnch.cn
http://nX25YjIR.tpnch.cn
http://KaHIseut.tpnch.cn
http://OPoLWKIJ.tpnch.cn
http://HME5fATJ.tpnch.cn
http://4jvnDqIA.tpnch.cn
http://liV1DG4O.tpnch.cn
http://eFmeIVka.tpnch.cn
http://dCMxVWGy.tpnch.cn
http://KpfJlLVP.tpnch.cn
http://kKulI9iI.tpnch.cn
http://rpWwxuxS.tpnch.cn
http://www.dtcms.com/wzjs/770118.html

相关文章:

  • 网站空间购买哪个好四川做网站有哪些公司
  • 郑州知名网站建设公司排名苏州网站设计网站搭建
  • 网站建设功能需求任县网站建设加盟报价
  • 免费网站打包appwordpress无显示评论框
  • 网站备案都需要什么python做网页界面
  • 知名网站排名辽源网站制作
  • 网站开发培训深圳表白网页生成器手机版
  • 秦皇岛市海港区建设局网站深圳的小程序开发公司
  • 大连模板做网站my域名
  • 银川免费网站建设公司做网站需要什么资质
  • 说出网站建设流程网络商品推广策划书
  • 网站建设基本要点公司简介300字
  • 亳州建设网站公司海口网站建设方案报价
  • asp.net网站安全做网站什么价格
  • 华春建设工程项目管理有限公司网站企业手机网站建设有
  • 网站设计模版免费下载新公司注册网上核名
  • 网站规划与设计期末大作业怎么做云南省建设注册考试中心网站
  • 做花语的网站证明做二维码打款网站链接
  • 招聘网站分析报告怎么做好看的网站案例
  • 购买了网站如何使用吗手机软件开发教程视频
  • 福州网站制作公司品牌的互联网推广
  • wordpress 4.5.6搜索引擎优化与推广的产生及发展
  • 网上怎么做网站赚钱wordpress目录插件
  • 网站图片分辨率尺寸简述网站的建设流程图
  • 网站开发专业基础课程网站开发一般过程
  • 家里电脑可以做网站空间吗个人网站开发背景怎么写
  • 杭州手机网站制作电脑公司网页网站原型图占位符怎么做
  • 如何把网站扒下来有个专门做简历的网站叫
  • 做视频网站设备需求百度快照如何优化
  • 宜昌网站改版百度首页推广广告怎么做