我正在寻找类似于
Arc
/Rc
的智能指针,只不过它不允许共享所有权。
我想要尽可能多的
rc::Weak
参考,但我只想要一个强参考,即所有者。我想通过类型系统强制执行这一点。
Arc
/Rc
可以克隆,并且可以在多个地方拥有。
滚动我自己的智能指针是一种选择,但我相信这样的数据结构应该已经存在,即使在标准库之外。
我正在寻找提供这种接口的数据结构:
impl MySmartPointer<T> {
fn new(object: T) -> Self;
fn weak_ref(&self) -> WeakRef<T>;
fn get_mut(&mut self) -> &mut T;
}
impl WeakRef<T> {
/// If the strong pointer `MySmartPointer` has been dropped,
/// return `None`. Else return Some(&T);
fn get(&self) -> Option<&T>;
}
假设它存在类型
Strong<T>
和 Weak<T>
。如何使用Weak<T>
?您需要某种容易出错的“升级”步骤,那么 Weak<T>
会升级到什么?它不能是一个简单的参考(如您所说),因为Strong<T>
需要知道是否存在任何“升级”Weak<T>
。如果没有,它可以在该值仍在被访问时释放其存储。
因此,
Weak<T>
必须升级到某种SemiWeak<T>
,以保持底层分配的活力……这正是共享所有权的。
如果您以某种方式保证
Strong<T>
在所有 Weak<T>
消失之前不会被释放怎么办?恭喜,您刚刚重新发明了 T
和 &T
:您实际上可以直接使用它们。
好吧,所以如果你做到了,那么
Weak<T>
升级为SemiWeak<'a, T>
,与Weak<T>
的生命周期相关联,因此它不能比它长,只能是暂时的?在这种情况下,您真正要做的就是“隐藏”您拥有共享所有权的事实。在幕后,SemiWeak
仍然需要保证底层的Strong
不会消失。您可以在大约十分钟内从 Rc<T>
轻松构建这样一个类型。这将有效地为您提供一种与 Rc<T>
完全相同的类型,具有相同的性能和内存成本,但用处较小。此外,那个
get_mut
方法不可能存在。没有办法阻止
SemiWeak<T>
的存在。除非您使用借用,但同样,这只是使用 T
和 &T
。所以,不,我认为这不存在,也不相信它能够以您所描述的形式出现。
最后说一句,仅仅拥有 Weak<T>
就是一种共享所有权的形式,因为那些
Weak<T>
需要指向某些东西。在 Rc<T>
的情况下,弱计数器与强计数器一起存储,因此虽然该值可以被销毁,但分配本身仍然存在。您可以将两者分开,但现在您要为两个分配和双重间接付费(可能会导致更多缓存未命中)。我知道这个线程很旧,但板条箱 refbox https://docs.rs/refbox/latest/refbox/index.html 似乎正是这样做的。我不知道使用起来有多安全,因为文档中称它是实验性的。