rust - 我的类似RefCell的结构上的rowe_mut()不起作用

标签 rust

我尝试编写自己的类似于RefCell的可变内存位置,但没有运行时借用检查(无开销)。我采用了RefCell(以及RefRefMut)的代码体系结构。我可以毫无问题地调用.borrow(),但是如果我调用.borrow_mut(),那么rust编译器会说cannot borrow as mutable。我没有看到问题,我的.borrow_mut() impl看起来不错吗?

失败的代码:

let real_refcell= Rc::from(RefCell::from(MyStruct::new()));
let nooverhead_refcell = Rc::from(NORefCell::from(MyStruct::new()));

// works
let refmut_refcell = real_refcell.borrow_mut();

// cannot borrow as mutable
let refmut_norefcell = nooverhead_refcell.borrow_mut();
norc.rs(无开销RefCell)
use crate::norc_ref::{NORefMut, NORef};
use std::cell::UnsafeCell;
use std::borrow::Borrow;

#[derive(Debug)]
pub struct NORefCell<T: ?Sized> {
    value: UnsafeCell<T>
}

impl<T> NORefCell<T> {

    pub fn from(t: T) -> NORefCell<T> {
        NORefCell {
            value: UnsafeCell::from(t)
        }
    }

    pub fn borrow(&self) -> NORef<'_, T> {
        NORef {
            value: unsafe { &*self.value.get() }
        }
    }

    pub fn borrow_mut(&mut self) -> NORefMut<'_, T> {
        NORefMut {
            value: unsafe { &mut *self.value.get() }
        }
    }

}
norc_ref.rs(由NORefCell.borrow[_mut]()返回的数据结构
use std::ops::{Deref, DerefMut};

#[derive(Debug)]
pub struct NORef<'b, T: ?Sized + 'b> {
    pub value: &'b T,
}

impl<T: ?Sized> Deref for NORef<'_, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        self.value
    }
}

/// No Overhead Ref Cell: Mutable Reference
#[derive(Debug)]
pub struct NORefMut<'b, T: ?Sized + 'b> {
    pub value: &'b mut T,
}

impl<T: ?Sized> Deref for NORefMut<'_, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        self.value
    }
}

impl<T: ?Sized> DerefMut for NORefMut<'_, T> {

    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        self.value
    }
}

最佳答案

NORefCell::borrow_mut()采用&mut self,这需要在包装它的DerefMut上加上一个Rc。这是行不通的,因为Rc不会仅仅通过很好地询问就给出可变的引用(您需要使用它来检查引用计数是否恰好是1,否则将有多个可变的借用)。
borrow_mut必须采用&self而不是&mut self

正如我的评论中提到的那样:您基本上要做的是在UnsafeCell周围提供一个看起来安全的抽象。这是非常危险的。注意有关UnsafeCell的文档:

The compiler makes optimizations based on the knowledge that &T is not mutably aliased or mutated, and that &mut T is unique. UnsafeCell is the only core language feature to work around the restriction that &T may not be mutated.



您正在为这个强大的对象提供一个瘦包装器,在API边界上没有unsafe。 “No-overhead-RefCell”实际上是“无触发器的护脚枪”。它确实有效,但仍会警告其危险。

关于rust - 我的类似RefCell的结构上的rowe_mut()不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59266854/

相关文章:

windows - 在磁盘上读取/写入文件时如何限制硬盘磁盘 I/O?

rust - rust 主fn读取目录结果错误无法编译

rust - 如何使用默认值压缩两个长度不等的迭代器?

rust - 在 Rust 中,如何修复错误 "the trait ` core::kinds::Sized` is not implemented for the type `Object+' a`"

rust - 类型不匹配的错误 : Option<&[u8]> and Option<&[u8;32]>

generics - 当参数不受约束时,如何为实现特征 Fn 的类型指定通用参数?

gcc - ld 找不到库,即使 ldconfig 找到了 (rust-sciter)

macros - 如何在隐式导出宏时使用模块中定义的构造

rust - to_string() 的稳定替代方案是什么

rust - 匹配枚举引用的语法是什么?