概述
经过对标准库源代码的学习,很容易能够发现,rust编译器提供的安全特性实际很少:
明确的安全特性:
- 变量必须初始化之后才能使用;
- 引用必须是内存对齐的,引用指向的变量必须已经初始化;
- 模块成员默认私有
- 严格的类型及类型无效值限制
- 基础类型都满足Copy/Send/Sync auto trait
明确的不安全特性:
- 裸指针解引用;
- 线程间转移变量必须支持Send, 共享变量必须支持Sync
- 所有的FFI调用,unsafe intrinsic函数调用
- 对类型产生无效类型值
- 嵌入式汇编使用
- 含有以上成分的代码单元
为安全提供的工具特性:
- 所有权,生命周期,自动drop;
- 自动解引用
可以看到,编译器提供的安全特性实际上只是实现内存安全的基础设施。RUST程序员仍然需要依靠这些基础设施来构建整个程序的安全大厦。
标准库提供了大量的语言类基础类型结构及操作系统相关的基础类型结构,并完成了这些基础类型结构的安全。如果仅仅使用标准库提供的类型结构,则一般不必额外考虑内存安全问题。但是如果超纲,则新的类型的内存安全必须由创建此类型的代码来做保证,而在当前RUST生态还不完善的情况下,这是必然要发生的事。
RUST的内存安全指的是编译器提供基础设施,程序员利用基础设施创建内存安全的类型结构使编译器能够保证这些类型的内存安全。
在标准库的实践中,可以发现安全是由大量的不安全代码所实现。尤其在操作系统适配的那一层次上,rust实际就是语法改变了的C,为了提高性能所采用的那些技巧和C毫无二致,令人发指,但又不得不佩服。这些代码的安全高度依赖于程序员,语言本身基本没有保障。
RUST的安全本质上仍然是一批高水平程序员实现的一个语言安全框架。
RUST官方语言库安全戏法的一些套路:
安全类型结构基本上是一个封装类型结构, 真正要操作的原始变量被封装在内,并且,此封装类型结构拥有原始变量的所有权。例如:RefCell, 智能指针,Rc,Arc,Mutex等。用于实现不同场景下的安全。
实现封装类型结构的Drop trait,完成生命周期结束时需要的清理操作,例如,释放堆内存,关闭文件描述符等
实现对封装类型结构的借用函数,对于复杂操作,往往需要一个额外的专用于借用的封装类型结构及可变借用的封装类型结构,如Ref, RefMut分别是RefCell的借用及可变借用的结构。不同的封装类型根据意义的不同会有不同的借用操作,如RefCell的borrow(), borrow_mut(), Rc的clone(), Mutex的lock(),但都是满足在某种安全机制下的获取原始变量的借用。
实现对于封装类型结构或者借用封装类型结构的Deref trait及 DerefMut trait,得到原始变量的引用或可变引用,从而实现对于原始结构的访问及更改。
实现对于借用封装类型的Drop trait,完成针对借用的清理工作,如减少计数,释放锁等。
RUST的安全实际上都是由这些安全封装类型完成。可以说,每一个安全封装类型都是程序员的血汗得来的教训。
从后继标准库的源代码分析中,可以真实的熟悉RUST的安全戏法。
自推荐:深入RUST标准库内核 目前在github上已经接近500星
最后
以上就是落寞歌曲为你收集整理的RUST内存安全杂述的全部内容,希望文章能够帮你解决RUST内存安全杂述所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复