7个版本
0.2.6 | 2024年1月28日 |
---|---|
0.2.5 |
|
0.2.4 | 2023年11月26日 |
0.2.3 | 2022年10月30日 |
0.1.0 | 2021年4月17日 |
#39 在 内存管理
每月94次下载
在 2 crates 中使用
76KB
817 行
来自GhostCell
论文的一个新颖的安全且零成本的借用检查范式。
动机
许多集合,如链表、二叉树或B树,最易通过别名指针实现。
传统上,这意味着使用运行时借用检查以仍然能够修改这些结构,或者为了性能而使用 unsafe
。
通过使用 品牌,GhostCell
将数据与其可变权限分开,并通过 品牌 使用唯一的 GhostToken
来建模这种权限,并将其与编译时的一组 GhostCell
相关联。
安全性
在GhostCell论文中,Joshua Yanovski和德国MPI-SWS的同事们使用他们作为RustBelt项目一部分开发的分离逻辑,正式证明了GhostCell
的安全性。我个人会相信他们。
官方实现可以在https://gitlab.mpi-sws.org/FP/ghostcell/-/tree/master/ghostcell找到,包括示例。现在我知道了,当前实现将会很快升级。
自行承担风险!
(并请报告任何问题)
成熟度
这是一个非常初级的Alpha质量版本,最多。
文档
- 所有方法都有文档。
- 所有非平凡方法都有示例。
测试
- 所有非平凡方法都经过测试,通过它们的示例。
- 所有带有安全性不变量的方法都包含编译失败测试。
- 整个测试套件,包括示例,都在Miri下运行。
如何使用?
让我们从一个自包含的示例开始。
use ghost_cell::{GhostToken, GhostCell};
fn demo(n: usize) {
let value = GhostToken::new(|mut token| {
let cell = GhostCell::new(42);
let vec: Vec<_> = (0..n).map(|_| &cell).collect();
*vec[n / 2].borrow_mut(&mut token) = 33;
*cell.borrow(&token)
});
assert_eq!(value, 33);
}
GhostToken
使用已知的最佳方式生成唯一的生命周期,因此用作品牌,这是将
- 一个局部变量,在
GhostToken::new
方法内部创建。 - 一个对所有生命周期都必须有效的闭包。
这意味着有两个限制
- 闭包必须对所有生命周期进行变体,这并不总是与已经包含引用的闭包很好地配合。
- 闭包不能返回任何品牌物品。
然后,在闭包内部,任何 GhostCell
都可以与一个且只有一个 GhostToken
关联,这将编码其借用权限
&GhostToken<'brand>
是使用GhostCell<'brand, T>::borrow
的关键——注意匹配的'brand
——并允许获取一个&T
引用。&mut GhostToken<'brand>
是使用GhostCell<'brand, T>::borrow_mut
的关键,并允许获取一个&mut T
引用。
使用 borrow
或 borrow_mut
借用 两个 单元和令牌。
那么呢?
GhostCell
是一个安全、零成本的单元。它允许在编译时进行借用的检查来别名。
结合 StaticRc
,它允许在安全的、稳定的 Rust 中编写双链表、二叉树和带父指针的 B 树等。
其他单元
还存在其他单元,执行类似功能,但具有不同的权衡
- 标准的
Cell
和RefCell
。 qcell
crate 的多个单元,其中LCell
基于与GhostCell
作者的讨论,共享类似的想法。
这就全部了!
感谢阅读。