unsafe:unsafe 的作用
几乎每个语言都有 unsafe 关键字,但 rust 语言使用 unsafe 的原因可能与其它编程语言还有所不同。
rust 中 unsafe 的存在主要原因是 rust 的静态检查强大且严格保守,这会导致编译器在分析一段代码时,无法分析出它的所有正确性,从而拒绝这段代码,触发编译错误。
特别是当编译器配合所有权系统一起使用时,有个别问题是真的棘手和难以解决。
unsafe 存在的另一个原因是:它必须要存在。因为计算机底层的一些硬件就是不安全的,如果 Rust 只允许你做安全的操作,那一些任务就无法完成。
rust 编译器不仅强大且严格保守,而且编译检查也是很难绕过的。通常想要绕过,最常用的方法就是 unsafe 和 Pin,并且这俩还有一定的限制。
unsafe 的五种超能力 (unsafe superpowers)
unsafe 不意味着块中的代码就一定是危险的或者必然导致内存安全问题,它只提供了五个不会被编译器检查内存安全的功能。
这意味着:unsafe 并不会关闭借用检查器或禁用任何其他 Rust 安全检查,例如在不安全代码中使用引用,它仍会受到编译器的检查。
使用原则一:没必要用时就不要用,当有必要用时就大胆用,但是尽量控制好边界,让 unsafe 的范围尽可能小。
因为就算内存访问出错了,也能立刻意识到错误是在 unsafe 代码块中,而不需要花大量时间像无头苍蝇一样去寻找问题所在。
因此写代码时要尽量控制好 unsafe 的边界大小,越小的 unsafe 越容易定位。
使用原则二:除了控制边界大小,另一个很常用的方式就是在 unsafe 代码块外包裹一层 safe 的 API,例如一个函数声明为 safe 的,然后在其内部有一块儿是 unsafe 代码。
五种超能力(unsafe superpowers):
- 解引用裸指针
- 调用不安全的函数或方法
- 访问或修改可变静态变量
- 实现不安全 trait
- 访问 union 的字段