所有权是Rust最独特的特性,它让Rust无需GC就可以保证内存安全,这个概念是非常重要的,Rust的核心特性就是所有权,所有的程序在运行时都必须管理它们使用计算机内存的方式
有些语言有GC、在程序运行时,它们会不断地寻找不再使用的内存,例如JavaScript这样的语言,还有一些语言,程序员必须显式的分配和释放内存,例如C语言等
而Rust采用了第三种方式,没错就是所有权,Rust内存是通过一个所有权系统来管理的,其中包含一组编译器在编译时检查的规则,当程序运行时,所有权特性不会减慢程序的运行速度、因为Rust把内存管理相关的工作都提前到了编译时
说到内存管理,那么Stack和Heap是不得不提的,很多语言程序员是不需要去关心栈内存和堆内存之间的区别的,而Rust则不然,Rust是系统级语言,一个值在Stack还是Heap上,对语言的行为以及我们为什么要做某些决定是有重大影响的,在我们代码运行时,Stack和Heap都是你可用的内存、但是它们的结构是不相同的
谈论到存储数据的话那么就不得不提及到数据结构了,Stack是按值的接受顺序来存储的、按相反的顺序进行移除,也就是我们常说的压栈和弹出栈,所有存储在Stack上的数据必须拥有已知的固定大小、编译时大小未知的数据或在运行时大小会发生变化的数据是必须存放在Heap上的
但相对于Stack来说,Heap内存组织性差一点,当你把数据放入Heap中,你将会请求一定数量的空间,操作系统在 Heap里找到一块足够大的空间,把它标记为在使用,并返回一个指针,也就是这个空间的地址,这个过程就是在Heap上分配,相比于Heap,把值压入到Stack上不能够称为分配,因为指针是已知固定大小的,可以把指针存放在Stack上,如果我们需要操作实际数据,我们可以使用指针来定位
把数据压入到Stack上是要比再Heap上分配快得多的,因为操作系统不需要寻找用来存储新数据的空间,压入的数据永远在Stack顶端,相反的在Heap上分配的空间需要做很多的工作,首先操作系统需要找到一块足够大的空间来存放数据,然后做好记录方便下次分配
在访问数据时Stack和Heap也是有很大的区别的:
第一个不同点无非就是速度问题,访问Heap中的数据是要比访问Stack上的数据慢的多的,因为需要通过指针才能找到heap中的数据,对于现代的处理器来说,由于缓存的缘故如果指令在内存中跳转的次数越少,那么速度将越快
如果数据存放的距离比较近,那么处理器的处理速度就会快一些,也就是将数据放在 Stack上
如果数据之间的距离比较远,那么处理速度就会慢一些,也就是将数据存放在Heap上
而且在Heap上分配大量空间也是需要时间的
关于 Stack 以及 Heap 的函数调用也是不同的:
当我们的代码调用函数的时候,值将会被传入到函数包括指向heap的指针、函数本地的变量被压到Stack上、当函数结束之后,这些值将会从Stack上弹出
谈论了这么多,无非就是想解释清除所有权的功能:
所有权可以跟踪代码哪些部分正在使用 Heap 的哪些数据,最小化 Heap 上的重复数据
清理heap上未使用的数据来避免空间不足,有了所有权,我们就不需要经常去想 Stack 和 Heap 了
所有权规则: