首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在我的类刷新单元结构上的borrow_mut()不能工作

在我的类刷新单元结构上的borrow_mut()不能工作
EN

Stack Overflow用户
提问于 2019-12-10 12:06:50
回答 1查看 493关注 0票数 0

我尝试编写自己的RefCell-like可变内存位置,但不需要运行时的借用检查(没有开销)。我采用了来自RefCell (以及RefRefMut)的代码体系结构。我可以毫无问题地调用.borrow(),但是如果我调用.borrow_mut(),那么生锈编译器就会说cannot borrow as mutable。我看不出问题所在,我的.borrow_mut()看起来很好吗?

失败的代码:

代码语言:javascript
复制
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)

代码语言:javascript
复制
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]()返回的数据结构)

代码语言:javascript
复制
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
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-10 14:56:02

NORefCell::borrow_mut()接受&mut self,它需要在包装它的Rc上设置一个DerefMut。这是行不通的,因为Rc仅仅通过很好地请求就不会提供可变的引用(您需要它来检查引用计数是否正好是一个,否则就会有多个可变的借方)。

borrow_mut不得不接受&self而不是&mut self

正如我在评论中提到的:您所做的基本上是围绕一个UnsafeCell提供一个安全的抽象。这太危险了。注意关于UnsafeCell的文档

编译器基于以下知识进行优化:&T不是可变的别名或变异,而且&mut T是唯一的。UnsafeCell是唯一的核心语言特性,可以绕过&T不能变异的限制。

您正在为这个强大的对象提供一个薄包装器,在API边界上没有unsafe。“不-头顶-冰箱”实际上是一种“无触发护卫脚枪”。它确实有效,但要警惕它的危险。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59266854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档