Rust smart point
Box 堆对象分配
表达式不能隐式地解引用
特意的将数据分配在堆上
fn main() { |
智能指针往往都实现了 Deref 和 Drop 特征,因此:
println! 可以正常打印出 a 的值,是因为它隐式地调用了 Deref 对智能指针 a 进行了解引用
最后一行代码 let b = a + 1 报错,是因为在表达式中,我们无法自动隐式地执行 Deref 解引用操作,你需要使用 * 操作符 let b = *a + 1,来显式的进行解引用
a 持有的智能指针将在作用域结束(main 函数结束)时,被释放掉,这是因为 Box 实现了 Drop 特征
数据较大时,又不想在转移所有权时进行数据拷贝
栈上数据转移所有权时,实际上是把数据拷贝了一份,最终新旧变量各自拥有不同的数据,因此所有权并未转移。
堆上则不然,底层数据并不会被拷贝,转移所有权仅仅是复制一份栈中的指针,再将新的指针赋予新的变量,然后让拥有旧指针的变量失效,最终完成了所有权的转移:
fn main() { |
类型的大小在编译期无法确定,但是我们又需要固定大小的类型时
其中一种无法在编译时知道大小的类型是递归类型:
/// 报错 |
特征对象,用于说明对象实现了一个特征,而不是某个特定的类型
在 Rust 中,想实现不同类型组成的数组只有两个办法:枚举和特征对象,前者限制较多,因此后者往往是最常用的解决办法。
trait Draw { |
以上代码将不同类型的 Button 和 Select 包装成 Draw 特征的特征对象,放入一个数组中,Box 就是特征对象。
其实,特征也是 DST 类型,而特征对象在做的就是将 DST 类型转换为固定大小类型。
Box::leak
Box::leak,它可以消费掉 Box 并且强制目标值从内存中泄漏
需要一个在运行期初始化的值,但是可以全局有效,也就是和整个程序活得一样久,那么就可以使用 Box::leak,例如有一个存储配置的结构体实例,它是在运行期动态插入内容,那么就可以将其转为全局有效,虽然 Rc/Arc 也可以实现此功能,但是 Box::leak 是性能最高的。
Deref
use std::ops::Deref; |
Self::Target “当前类型解引用后所得到的目标类型”

