1 个不稳定版本
0.1.0 | 2020 年 3 月 19 日 |
---|
#2440 在 Rust 模式
在 skew-forest 中使用
9KB
66 行
debug-tag
创建仅调试标记以跟踪和检查值使用的库。
用于断言两个值源自同一来源很有用。例如,两个节点上的操作可能仅在节点位于同一图中时才有效。《DebugTag》可以用于测试和调试时检查这一点。
有关更多信息,请参阅《DebugTag》类型。
动机
当开发 Rust 时,我们经常使用 索引 来引用其他值而不是使用 指针。使用索引允许我们“指向”一个值而不借用它,并且基本上可以视为以限制性方式绕过借用检查。
使用索引的一个问题是,它在编译时并未与存储值的容器相关联。与错误容器一起使用的索引可能会引发恐慌,或者更糟,返回垃圾值。
我们需要一种方法来“标记”值,以便我们可以确定是否使用了正确的容器。
示例
use debug_tag::DebugTag;
/// An example vec-like structure that allows pushing values and getting values by index.
#[derive(Default)]
struct Slab<T>{
items: Vec<T>,
tag: DebugTag,
}
/// An index into a value on a slab.
#[derive(Copy, Clone)]
struct Index {
index: usize,
tag: DebugTag,
}
impl<T> Slab<T> {
/// Pushes a new value onto the slab.
fn push(&mut self, item: T) -> Index {
let index = self.items.len();
self.items.push(item);
Index {
index,
tag: self.tag
}
}
/// Gets a value in this `Slab`. If the index is not from this slab, either panics or
/// returns an arbitrary value.
fn get(&self, index: Index) -> &T {
assert_eq!(self.tag, index.tag, "Index must stem from this slab");
&self.items[index.index]
}
}
let mut slab_a = Slab::default();
let ix = slab_a.push(42);
assert_eq!(slab_a.get(ix), &42);
let mut slab_b = Slab::default();
slab_b.push(1337);
// Panics due to the tags being checked:
// assert_eq!(slab_b.get(ix), &1337);
在没有 DebugTag
的情况下,上述最后一行将仅返回 1337 - 一个“垃圾值”,因为 ix
来自不同的 Slab
。
许可证:MIT