Rust 圣经 阅读 所有权和借用

所有权

栈(Stack)与堆(Heap)

栈何和堆的核心目标就是为程序在运行时提供可供使用的内存空间。

栈按照顺序存储值并以相反顺序取出值,后进先出。
增加数据叫进栈,取出数据叫出栈。
栈中的所有数据必须占用 已知且固定大小的空间。假设数据大小是未知的,那么在取出数据时,将不能取出想要的数据。

对于大小未知或可能变化的数据,我们需要将其存储在堆上。

当向堆上存储数据时,需要请求一定大小的空间,然后操作系统在堆的某处找到符合大小的空间,将其标注为已使用,并返回一个表示该位置地址的指针。该过程被称为在堆上分配内存。有时简称为”分配(allocation)“。

返回的指针会被推入栈中,因为指针的大小是已知且固定的,在后续使用中,可以通过指针,来获取数据在堆上的实际内存位置,进而访问数据。

堆上的数据是无组织的。

性能区别

写入方面:入栈比在堆上分配内存要快。
因为入栈只需将新数据放在栈顶,而在堆上分配内存需要找到足够存放数据空间,还要做一些记录为下次分配做准备。

读取方面:出栈比从堆上读取数据更快。
首先,栈上的数据都是存储在CPU的高速缓存上,而堆上的数据只能存储在内存中。而高速缓存和内存的访问速度差异在10倍以上。
其次,访问堆上数据,必须先访问栈再通过栈上的指针来访问内存。

所有权和堆栈

当调用一个函数,传递给函数的参数(包括指向堆的指针和函数的局部变量)一次压入栈中,当函数调用结束时,这些值将中栈中按照相反的顺序依次移除。
所有权帮助避免内存泄漏。

所有权原则

规则:

  1. Rust 中每一个值都被一个变量所拥有,该变量称为值的拥有者。
  2. 一个值同时只能被一个变量拥有,一个值只能有一个拥有者。
  3. 当所有者(变量)离开作用域范围时,这个值将被丢弃(drop)。
String 类型

动态字符串类型: String,该类型被分配到堆上,因此可以动态伸缩,可以存储在编译时大小未知的文本。

基于字符串字面量来创建 String 类型:

let s = String::from("hello");

:: 是一种调用操作符,表示调用 String 中的 from 方法,因为 String 存储在堆上的动态的,所有它可以修改。

let mut s = String::from("hello");

s.push_str(", world!"); // push_str() 在字符串后追加字面值

println!("{}", s); // 将打印 `hello, world!`

变量绑定背后的数据交互

转移所有权
let x= 5;
let y = x;

5 绑定到变量 x;接着拷贝 x 的值赋给 y,最终 xy 都等于 5,因为整数是 Rust 基本数据类型,是固定大小的简单值,因此这两个值都是通过自动拷贝的方式来赋值的,都被存在栈中,完全无需在堆上分配内存。

只有存储在栈上的基本类型,rust 会自动拷贝。

let s1 = String::from("hello");
let s2 = s1;

String 不是基本类型,而且是存储在堆上的,因此不能自动拷贝。

实际上, String 类型是一个复杂类型,由存储在栈中的堆指针

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值