Rust初学者大多会遇到这样的问题:

  • 为什么同一资源不可被同时可变借用和不可变借用?
  • 为什么Rc一定只能是只读的,一定要配合std::cell系列(Cell,RefCell,UnsafeCell)才能提供可变性?为什么不设计一个可变的Rc?
  • 为什么Mutex/RwLock一般都会配合Arc使用?

    ……

这一类借用规则的问题,实际上都可以通过另一种思路来很好地解答,当然这也是很多大佬一定程度上认可的理解方式:

Rust中的借用,分为不可变借用共享借用,和可变借用独占借用

无论在教程中,还是语法中,我们都用可变性来区分二种借用,最开始,最直观的理解:

  • 因为是可变借用,多方借用会导致冲突,因此可变借用是独占的。
  • 因为是不可变借用,多方借用只读数据不会导致冲突,因此不可变借用是可共享的。

但是我们可以试着换一个方向去思考,用独占性去区分两种借用,很多问题便可以轻易理解:

  • 因为是独占借用,对资源的任何形式的访问都只能有一方可以被允许,所以对它的改变是安全无害的。
  • 因为是共享借用,对资源的访问可以有多方共同进行,所以对其中任何一方而言,来自其他方的改变是不可控的,所以对它的改变并不是安全无害的,因此它只允许只读访问。

这样的思考方式从“可变性==>独占性”换成了“独占性==>可变性”,首先就直观地解释了“同一资源不可同时被可变借用和不可变借用”的问题,因为“独占借用”从字面上就不可能跟其他任何形式的借用共存。

再说到Rc/Arc。Rc是通过引用计数来提供安全的共享访问的只能指针,在C++中本就叫做"shared_ptr",从逻辑上就是提供共享访问的工具,不应被任何一方独占,因此也理应只提供共享借用。而Arc就是线程安全版的Rc。

无论是std::cell系列还是Mutex/RwLock,它们的目的都一致:为共享资源提供安全的可变访问。由于既需要共享,也需要可变,因此无法用“独占=可变,共享=不可变”的类型模型去编译期检查访问的安全性,只能在运行时通过实际的行为去动态检查,保证“同一时间,一个资源只可以被一方可变访问,或被多方不可变访问”的原则。只是它们的行为略有不同:

  • UnsafeCell仅仅是一层包装壳,在对本身的访问不需要所有权或独占借用,仅提供共享借用的前提下,提供对内含资源的独占引用访问,因为没有任何策略保证访问的安全,因此对其的操作是unsafe的。
  • Cell屏蔽掉了UnsafeCell的引用访问,只提供存取访问。由于在单线程下,调用函数即完全交出控制权,存取都可被视为原子操作,而资源本身也从一个静态的资源变成了一个需要操作去存取的读写对象,因此自然也保证了安全访问的原则。
  • RefCell在UnsafeCell的基础上,以性能为代价,加入了运行时检查机制以提供安全的引用访问。由于引用可以在调用结束后持续地被持有,因此需要guard(通过自身的RAII来控制目标资源的占用与解除占用的结构)来运行时监控当前资源被访问的形式和数量,在打破安全访问的原则时及时抛出panic来避免ub。
  • RwLock是线程安全版的RefCell,通过调用系统底层的线程锁来实现线程安全,在打破安全访问原则时阻塞后续的访问而不是panic,以等待目前的占用解除。
  • Mutex是只读访问互斥版的RwLock,即使不存在可写访问,仍然会在已有只读访问占用时阻塞后续的只读访问。

不难看出,很多情况下,Arc<RwLock>的组合实际上跟Rc<RefCell>的逻辑是一致的:在需要共享的可变资源时,先用Rc/Arc控制资源的生命周期,再用RefCell/RwLock来控制资源的访问安全,区别在于是否为跨线程访问提供支持。

综上所述,以个人经验来讲,在习惯上以独占借用/共享借用的视角来分析,而不是可变借用/不可变借用,更有助于理解借用规则的实质,希望以此可以给初接触Rust的同行一些启发。

Rust借用机制的理解分析的更多相关文章

  1. Springboot学习04-默认错误页面加载机制源码分析

    Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...

  2. Android事件分发机制源码分析

    Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...

  3. Redis数据持久化机制AOF原理分析一---转

    http://blog.csdn.net/acceptedxukai/article/details/18136903 http://blog.csdn.net/acceptedxukai/artic ...

  4. 浅谈 Attention 机制的理解

    什么是注意力机制? 注意力机制模仿了生物观察行为的内部过程,即一种将内部经验和外部感觉对齐从而增加部分区域的观察精细度的机制.例如人的视觉在处理一张图片时,会通过快速扫描全局图像,获得需要重点关注的目 ...

  5. [转]as3事件流机制彻底理解

    题记: 看过网上一些as3事件流的教程,觉得大多都讲得不甚清楚,让人不能直观的理解事件流.而这篇教程以将事件流过程比喻成捕鱼过程,形象简单. 在此基础上对于as3事件流总算有了全面的理解.事件流机制说 ...

  6. Linux内核OOM机制的详细分析(转)

    Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...

  7. 我对asp.net运行机制的理解

    有一本书叫<asp.net 本质论>,作者名叫冠军.我看了几次,都没有坚持看下来.这次连续看完了前三章,然后参考网上的资料,总结下我对.net运行机制的理解. 先上两张图: 看着这两张图, ...

  8. JDK动态代理深入理解分析并手写简易JDK动态代理(下)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...

  9. JDK动态代理深入理解分析并手写简易JDK动态代理(上)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...

随机推荐

  1. FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  2. docker 部署 zabbix

    docker部署zabbix   我相信大家都已经会再物理机上跑zabbix并且监控了,那么有没有想过在docker中跑zabbix?下面咱们来看看如何在docker中搭建zabbix并且监控 部署环 ...

  3. 【Linux常用命令①】程序员必须掌握的Linux命令

    目录 man:帮助命令 echo:输出 date:时间 reboot:重启 poweroff:关闭系统 wget:下载 ps:查看进程状态 top:任务管理器 pidof:查询某个指定进程的PID值 ...

  4. 每天一个dos命令-del.

    比较常用的选项: /F 强制删除只读文件. /Q 安静模式.删除全局通配符时,不要求确认 文件名或者路径中有空格,需要使用引号包围 常用的实例:del  /q/f   c:\Securitylog\S ...

  5. 每日一个知识点系列:volatile的可见性原理

    每日一个知识点系列的目的是针对某一个知识点进行概括性总结,可在一分钟内完成知识点的阅读理解,此处不涉及详细的原理性解读. img 看图说话 关键点1: 总线嗅探器(MESI 缓存一致性原理 ) 关键点 ...

  6. C#设计模式-适配器模式(Adapter Pattern)

    概念 把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作.适配器模式有类的适配器模式和对象的适配器模式两种形式.前者类之间的耦合度比后者高,且要求程 ...

  7. osgEarth使用笔记1——显示一个数字地球

    目录 1. 概述 2. 实现 2.1. 三维显示 2.2. 二维显示 1. 概述 osgEarth支持.earth格式的文件,里面保存了数字地球相关信息的配置XML,只需要读取这个配置文件,就可以直接 ...

  8. GAN训练技巧汇总

    GAN自推出以来就以训练困难著称,因为它的训练过程并不是寻找损失函数的最小值,而是寻找生成器和判别器之间的纳什均衡.前者可以直接通过梯度下降来完成,而后者除此之外,还需要其它的训练技巧. 下面对历年关 ...

  9. CodeForces 79D 【Password】,洛谷P3943 【星空】

    其实我做的是洛谷的P3943,但是听说fstqwq窃题...... 题目描述: 小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点.不过,有 着强迫症的小 F 发现,这串一共 ...

  10. 手把手教你AspNetCore WebApi:认证与授权

    前言 这几天小明又有烦恼了,之前给小红的接口没有做认证授权,直接裸奔在线上,被马老板发现后狠狠的骂了一顿,赶紧让小明把授权加上.赶紧Baidu一下,发现大家都在用JWT认证授权,这个倒是挺适合自己的. ...