相关的概念
- 指针:一个变量在内存中包含的是一个地址(指向其它数据)
- Rust中最常见的指针就是“引用”
- 引用:
- 使用&
- 借用它指向的值
- 没有其余开销
智能指针
- 智能指针是这样的一些数据结构:
- 行为和指针类似
- 有额外的元数据和功能
- 引用计数(reference counting)智能指针类型
- 通过记录所有者的数量,使一份数据被多个所有者同时持有
- 并在没有任何所有者时自动清理数据
- 引用和智能指针的其它不同
- 引用: 只借用数据
- 智能指针: 很多时候都拥有它所指向的数据
- 智能指针的例子
- string和 vec
- 都拥有一片内在区域,且允许用户对其操作
- 还拥有元数据(例如容量等)
- 提供额外的功能或保障(string保障其数据是合法的utf-8编码)
- 智能指针的实现
- 智能指针通常使用struct实现,并且实现了:
- deref 和 drop这两个trait
- deref trait: 允许智能指针struct的实例像引用一样使用
- drop trait:允许你自定义当智能指针实例走出作用域时的代码
- 智能指针通常使用struct实现,并且实现了:
本章内容
- 介绍标准库常见的智能指针
- Box: 在heap内在上分配值
- Rc: 启用多重所有权的引用计数类型
- Ref和refmut,通过Refcell访问:在运行时而不是编译时强制借用规则的类型
- 此外:
- 内部可变模式(interior mutability pattern):不可变类型暴露出可修改其内部值的api
- 引用循环(reference cycles):它们如何泄露内在,以及如何防止其发生。
使用Box来指向Heap上的数据
- Box
- 最简单的智能针指针
- 允许你在heap上存储数据(而不是stack)
- stack上是指向heap数据的指针
- 没有性能开销
- 没有其它额外功能
- 实现了deref trait 和 drop trait
- 常用场景
- 在编译时,某类型的大小无法确定。但使用该类型时,上下文却需要知道它的确切大小。
- 当你有大量数据,想移交所有权,但需要确保在操作时数据不会被复制
- 使用某个值时,你只关心它是否实现了特定的trait,而不关心它的具体类型
fn main() { let b = Box::new(5); println!("b = {}", b); }
- 使用box赋能递归类型
- 在编译时,Rust需要知道一个类型所占的空间大小
- 而递归类型的大小无法在编译时确定
- 但Box类型的大小确定
- 在递归类型中使用Box就可解决上述问题
- 函数式语言中的Cons List
- 关于 Cons List
- Cons List 是来自Lisp语言的一种数据结构
- Cons List 里每个成员由两个元素组成
- 当前项的值
- 下一个元素
- Cons List里最后一个成员只包含Nil值,没有下一个元素
- Cons List不是最常用的集合
- Vec 是更好的选择
- 创建一个Cons List
enum List { Cons(i32, List), Nil, } fn main() {} enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), } fn main() {}
- 最简单的智能针指针
- 使用Box来获得确定大小的递归类型
- Box是一个指针,Rust知道它需要多少空间,因为:
- 指针的大小不会基于它指向的数据的大小变化而变化
- Box
- 只提供了“间接”存储和heap内存分配的功能
- 没有其它额外功能
- 没有性能开销
- 适用于需要“间接”存储的场景,例如Cons List
- 实现了Deref trait 和 Drop trait
- Box是一个指针,Rust知道它需要多少空间,因为: