- 不安全Rust:舍弃Rust的某些安全保障并负责手动维护相关规则。
- 高级trait:关联类型、默认类型参数、完全限定语法( fully qualified syntax ) 、 超 trait ( supertrait ) , 以 及 与trait相关的newtype模式。
- 高级类型:更多关于newtype模式的内容、类型别名、never类型和动态大小类型。
- 高级函数和闭包: 函数指针与返回闭包。
- 宏: 在编译期生成更多代码的方法。
1、不安全Rust:
在Rust中存在一种不会强制实施内存安全保障的语言:不安全Rust(unsafe Rust)。
不安全Rust之所以存在是因为静态分析从本质上讲是保守的。当编译器在判断一段代码是否拥有某种安全保障时,它总是宁可错杀一些合法的程序也不会接受可能非法的代码。尽管某些代码也许是安全的,但目前的Rust编译器却可能会做出相反的结论!
另外一个需要不安全Rust的原因在于底层计算机硬件固有的不安全性。如果Rust不允许进行不安全的操作,那么某些底层任务可能根本就完成不了。
(1)、不安全超能力:
可以在代码块前使用关键字unsafe来切换到不安全模式,并在被标记后的代码块中使用不安全代码。不安全Rust允许你执行4种在安全 Rust 中 不 被 允 许 的 操 作 , 而 它 们 也 就 是 所 谓 的 不 安 全 超 能 力(unsafe superpower)。这些能力包括:
- 解引用指针;
- 调用不安全函数;
- 访问或修改可变的静态变量;
- 实现不安全的trait。
注:unsafe关键字并不会关闭借用检查器或禁用任何其他Rust安全检查:如果在不安全代码中使用引用,那么该引用依然会被检查。unsafe关键字仅仅让你可以访问这4种不会被编译器进行内存安全检查的特性。因此,即便是身处于不安全的代码块中,你也仍然可以获得一定程度的安全性。
(2)、解引用裸指针:
与引用类似,裸指针要么是可变的,要么是不可变的,它们分别被写作*const T
和*mut T
。这里的星号是类型名的一部分而不是解引用操作。在裸指针的上下文中,不可变意味着我们不能直接对解引用后的指针赋值。
裸指针与引用、智能指针的区别在于:
- 允许忽略借用规则,可以同时拥有指向同一个内存地址的可变和不可变指针,或者拥有指向同一个地址的多个可变指针。
- 不能保证自己总是指向了有效的内存地址。
- 允许为空。
- 没有实现任何自动清理机制。
(3)、调用不安全函数或方法:
第二种需要使用不安全代码块的操作便是调用不安全函数(unsafe function)。除了在定义前面要标记unsafe
,不安全函数或方法看上去与正常的函数或方法几乎一模一样。此处的unsafe
关键字意味着我们需要在调用该函数时手动满足并维护一些先决条件,因为Rust无法对这些条件进行验证。
因为不安全函数的函数体也是unsafe
代码块,所以可以在一个不安全函数中执行其他不安全操作而无须添加额外的unsafe
代码块。