1 个不稳定版本

0.1.0 2020 年 3 月 19 日

#2440Rust 模式


skew-forest 中使用

MIT 许可证

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

无运行时依赖