位置: 首页 > 资讯 > 正文

Rust学习笔记Day17 智能指针之Box|世界速看

来源:哔哩哔哩   发表于: 2023-02-01 23:00:39  

经过这一段时间的学习,基础知识里,我们还剩数据结构没有学习,而数据结构里最难的就是智能指针

我们先回顾一下指针:它的值是一个内存地址,要想访问它指向的这个内存地址,需要解引用。理论上可以解引用到任意数据类型;引用是一个特殊的指针,它只能解引用到它引用的数据类型


【资料图】

智能指针

智能指针除了指向数据的指针外,还有源数据以提供额外的处理能力。

智能指针与胖指针的区别:智能指针一定是一个胖指针,但胖指针不一定是一个智能指针。

我们来看一个例子:

String(智能指针) 对堆上的值有所有权,而 &str(胖指针) 是没有所有权的,这是 Rust 中智能指针和普通胖指针的区别。

从String的定义来看明明就是个结构体,怎么就高攀上了智能指针了呢?这是因为String 实现了 我们昨天刚学的 Deref 和 DerefMut 这2个trait,这使得它在解引用的时候,会得到 &str。

由于在堆上分配了数据,String 还需要为其分配的资源做相应的回收。而 String 内部使用了 Vec,所以它可以依赖 Vec的能力来释放堆内存。

现在我们发现,在Rust中,但凡是要回收资源,并实现了Deref/DerefMut/Drop这3个trait的数据结构,都是智能指针

这么说的话,我们发现以下这些都是智能指针

用于在堆上分配内存的Box<T> 和 Vec <T>、

用于引用计数的 Rc<T> 和 Arc <T>

还有很多其他的数据结构 PathBuf、Cow <'a B>、MutexGuard <T> 等。

Box<T>

它是 Rust 中最基本的在堆上分配内存的方式,绝大多数其它包含堆内存分配的数据类型,内部都是通过 Box完成的,比如 Vec<T>。

我们先来复习一下C是怎么分配堆内存的。C提供了malloc/calloc/realloc/free 来处理内存分配,但是最后为了安全释放内存,给我们码农造成比较大的心智负担。

C++发现这个问题,于是搞了一个智能指针unique,可以在指针退出作用域的时候释放堆内存,这样保证了堆内存的单一所有权。这就是Box<T>的前身。

我们看到在Box<T>的定义里就有Unique表示借鉴的C++

堆上分配内存的 Box其实有一个缺省的泛型参数 A,就需要满足 Allocator trait,这其实是指定一种内存分配器,并且默认是 Global,当然也可以替换成自己的内存分配器。

Allocator trait 提供很多方法:

allocate 是主要方法,用于分配内存,对应 C 的 malloc/calloc;

deallocate,用于释放内存,对应 C 的 free;

还有 grow / shrink,用来扩大或缩小堆上已分配的内存,对应 C 的 realloc。

再来看下Box的Drop实现:

可以看到这是个空的实现。像我们平时开发一样,先确定接口,然后各自去自己的服务里实现自己的逻辑。这是不是就是我们一直说的面向接口编程的思想?

关键词: 数据结构 数据类型 释放内存

上一条:深圳市人才大市场_关于深圳市人才大市场的基本详情介绍-全球视点

下一条:最后一页