Cell<T>
与RefCell<T>
有什么关联与差别
它们之间的相同点
- 它们都是【共享+可修改】容器数据结构,而不是【智能指针】,因为其没有实现
Deref trait
或DerefMut trait
。 - 它们都只能被使用在【单线程】环境下,因为其皆未实现
Sync trait
。 - 它们都允许内部值
T
以受控方式被“修改”,虽然其已经同时被多个【只读-引用】所指向。- 对于
Cell<T>
与RefCell<T>
而言,“修改”这个词的含义是不一样的:- 前者只能算是【替换】(内部值
T
)--- 【可修改】是就Cell<T>
自身而言的,Cell<T>
内部值变了(别管怎么变的),反正Cell<T>
的值就是不一样了。感觉它偷换概念,欺负我读书少 - 后者才是【修改】--- 【可修改】是就内部值
T
所在内存地址上的内容而言的,内部值T
的内存位置没有变,而是那个地址上的东西变了。这明显更高级,因为它实至名归
- 前者只能算是【替换】(内部值
- 它们提供的这个能力被统称为【内部可修改】。这是相较于普通
rust
类型的【继承可修改】而言。
- 对于
- 它们仅只”打破“了传统的“【只读引用】不能与【可修改引用】共存”的限制。但是,在【同一时刻+同一作用域】内,【可修改引用】还至多只能有一个。否则,要么,编译错误;要么,运行时崩溃。
它们之间的不同点
上图的文字描述如下:
本质不同
Cell<T>
“包含”的是【所有权】变量本身RefCell<T>
“包含”的是变量的【引用】。即便RefCell::new(...)
构造函数的实参是【所有权】变量,这也不影响其内部重点使用该变量的【内存地址】。
衍生不同
- 检查时间点
Cell<T>
编译时,代码静态扫描,借入检查RefCell<T>
运行时,动态跟踪,借入检查- 运行时,确保:对内部值【临时的+排他的+可修改的】访问
- 违背【借入规则】的后果
Cell<T>
违背【借入规则】的代码会导致【编译失败】RefCell<T>
违背【借入规则】的代码会导致【运行时-程序崩溃panic
】
- 计算成本
Cell<T>
编译时成本RefCell<T>
运行时成本
- 读取【容器数据结构】内部值
Cell<T>
- 要么,将【内部值】复制出来。比如,
Cell<T: Copy>::get()
- 要么,将【内部值】置换出来。比如,
Cell<T: Default>::take()
以类型默认值置换出来Cell<T>::replace()
以指定的值置换出来
- 要么,“杀鸡取卵”将【容器数据结构】“消费
consume
”掉,再将【内部值】真取出来。比如,Cell<T>::into_inner()
- 要么,将【内部值】复制出来。比如,
RefCell<T>
就三步:- 通过【运行时-借入检查器】的审查
RefCell<T>::borrow()
取出变量的内存地址*RefCell<T>::borrow()
以【去引用-操作符】取出该地址位置上被保存的值。
- 修改【容器数据结构】内部值:
Cell<T>
Cell<T>::replace()
以【新】值置换出【旧】值Cell<T>::set()
放入【新】值而直接丢弃【旧】值
RefCell<T>
- 通过【运行时-借入检查器】的审查
RefCell<T>::borrow_mut()
取出变量的内存地址*RefCell<T>::borrow_mut()
以【去引用-操作符】修改该地址位置上被保存的值。
1
共 0 条评论, 1 页
评论区
写评论还没有评论