2 个不稳定版本
0.1.0 | 2021年4月11日 |
---|---|
0.0.1 | 2021年3月26日 |
#38 在 #垃圾
用于 bronze_gc
4KB
50 行
Bronze
安装
要使用 Bronze,您必须使用 Rust 的夜间工具。要安装它们,请在命令行中运行 rustup default nightly
。
使用方法
有时,Rust 中所有权的约束可能难以处理。例如,在 Rust 中实现双向链表非常困难,因为每个节点都必须被引用两次。此外,特别是对于正在学习 Rust 的人来说,暂时避免“每个变量只有一个所有者”的约束可能更容易。
Bronze 通过引入一种新的智能指针类型 GcRef,放宽了 Rust 的某些约束,GcRef 描述了一个指向垃圾回收堆位置的指针。使用 Bronze 时,位于 堆栈 上的数据具有所有常见的 Rust 所有权要求。然而,Bronze 允许将数据移动到 堆。如果类型 T
的值位于堆上,Bronze 允许多个 GcRef<T>
类型的引用指向该值。
例如,没有 Bronze,我们必须仔细管理引用和生存期
pub struct IntContainer {
n: i32,
}
pub fn set(c: &mut IntContainer, n: i32) {
c.n = n;
}
pub fn test() {
let c1 = IntContainer{n: 42};
let mut c2 = c1;
// Can't use c1 anymore because it's been moved to c2
set(&mut c2, 42);
}
使用 Bronze,非 Copy
类型的类型可以通过智能指针自由引用,这些智能指针 是 Copy
//
#[derive(Trace, Finalize)]
pub struct IntContainer {
n: i32,
}
pub fn set(mut c: GcRef<IntContainer>, n: i32) {
c.n = n;
}
pub fn test() {
let c1 = GcRef::new(IntContainer{n: 42});
let c2 = c1;
// Now c1 and c2 both reference the same object.
set(c2, 42);
set(c1, 43);
// Now they both reference an object with value 43.
}
因为 GcRef
实现了 Deref
,并且因为 Rust 会自动在需要时插入 *
,所以您可以通常将 GcRef<T>
视为直接是 T
。例如,在上面的 set()
中,主体将值赋给 c.n
。这隐含地意味着要取消引用指针并将值赋给引用值内部的 n
。如果您愿意,您也可以调用 as_ref()
和 as_mut()
来获取 GC 堆中数据的引用或可变引用。
要创建一个新的 GcRef<T>
,请调用 GcRef::new(e)
,其中 e
是你希望存在于 GC 堆上的值的表达式。
高级用法
如果你需要从 GC 堆中删除数据,可以使用 GcNullableRef
而不是 GcRef
。你可以使用 Gc::new_nullable
来创建一个。 GcNullableRef
与 GcRef
类似,但增加了一个 remove
方法。第一次调用 remove
会返回一个填充有之前在 GC 堆中数据的 Option
。后续调用 remove
返回 None。
实验性实现
此实现是 实验性的。特别是,收集器将不会运行;请注意,你最终会耗尽内存。然而,当前版本适合实验和原型设计。
依赖关系
~1.5MB
~38K SLoC