我该如何创建一个一次性的可变引用?

4

我正在尝试包装一个向量来更改其索引行为,这样当发生越界访问时,它将返回对虚拟值的引用,而不是触发错误。

use std::ops::Index;

struct VecWrapper(Vec<()>);

impl Index<usize> for VecWrapper {
    type Output = ();
    fn index(&self, idx: usize) -> &() {
        if idx < self.0.len() {
            &self.0[idx]
        } else {
            &()
        }
    }
}

这对于Index的实现来说完全没问题,但是用同样的方式实现IndexMut会因为显而易见的原因失败。我的集合类型没有Drop实现,因此不需要调用析构函数(除了释放内存)。

我能想到的唯一解决方案是拥有一个包含数千个虚拟元素的静态可变数组,并分配对该数组元素的引用,但这仍然是一个可怕的解决方案,如果借用的虚拟元素数量超过静态数组的大小,它仍然会导致UB。


当出现越界访问时,您将如何调试不可避免的奇怪问题? - Sebastian Redl
也许你只想获取 .get 而不是索引你的原始向量?这更符合惯用法,减少了样板代码,并且每个人都能理解阅读你的代码。 - jthulhu
我不害怕那种奇怪的情况,预期的行为是任何写出界的数据都会被丢弃,并且不会影响其他任何东西。 - terepy
()是真正的类型吗? - Chayim Friedman
1
相关:为稀疏向量实现索引/重载[]运算符 - Chayim Friedman
1个回答

6
给包装器添加一个额外字段,名为dummy。它有与先前变量相同的生命周期限制,因此不能被别名引用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接