在 https://rustx-labs.github.io/effective-rust-cn/chapter_1/item8-references&pointer.html 这本书中第8条
use std::cell::RefCell;
let rc: RefCell<u64> = RefCell::new(42);
let b1 = rc.borrow();
let b2 = rc.borrow();
其中的 b1,b2 为什么会画成胖指针?
Ext Link: https://rustx-labs.github.io/effective-rust-cn/chapter_1/item8-references&pointer.html
1
共 6 条评论, 1 页
评论区
写评论设计成两个指针就是空间换时间并且简化设计,设计成一个指针那deref实现就需要两次解引用,实在没必要。
因为RefCell是在运行时检测共享和可变性的,所以borrow借用时,还需要保留借用状态指针吧,以便在自动归还(drop)时,可以修改RefCell的借用状态,这部分就需要第二个指针。 有一个掩耳盗铃的方式[doge]可以这样写:
但是还是会有一个匿名的Ref对象存在于整个借用作用域内,而且再也没法手动去drop它了[doge]只能离开作用域自动释放
👇
xuejianxinokok: 为什么会这样设计? 一个指针搞不定吗?
pub fn borrow(&self) -> Ref<'_, T>
是返回
为什么会这样设计? 一个指针搞不定吗?
--
👇
Neutron3529: 查看源码可知,.borrow()返回的是一个 Ref<'_>对象,
Ref<'_>
的布局就是俩指针,一个指向value: NonNull<T>
,另一个指向borrow: BorrowRef<'b>
。进一步的搜索可知
因此这里的borrow是俩指针
因为Ref/RefMut需要支持map_split把一个Ref/RefMut拆成多个Ref/RefMut,所以引用计数指针和Deref指针要分开两个字段,不然一个指向RefCell的指针加上固定偏移就可以了;
查看源码可知,.borrow()返回的是一个 Ref<'_>对象,
Ref<'_>
的布局就是俩指针,一个指向value: NonNull<T>
,另一个指向borrow: BorrowRef<'b>
。进一步的搜索可知
因此这里的borrow是俩指针