|
|
@ -13,7 +13,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
举个例子,在之前的自引用章节中,我们就提到了相关的编译检查是很难绕过的,如果想要绕过,最常用的方法之一就是使用 [`unsafe` 和 `Pin`](https://course.rs/advance/circle-self-ref/self-referential.html)。
|
|
|
|
举个例子,在之前的自引用章节中,我们就提到了相关的编译检查是很难绕过的,如果想要绕过,最常用的方法之一就是使用 [`unsafe` 和 `Pin`](https://course.rs/advance/circle-self-ref/self-referential.html)。
|
|
|
|
|
|
|
|
|
|
|
|
好在,当遇到这些情况时,我们可以使用 `unsafe` 来解决。此时,你需要替代编译器的部分职责对 `unsafe` 代码的正确性负责,例如在正常代码中不可能遇到的空指针解引用问题在 `unsafe` 中就可能会遇到,我们就需要自己来处理好这些类似的问题。
|
|
|
|
好在,当遇到这些情况时,我们可以使用 `unsafe` 来解决。此时,你需要替代编译器的部分职责对 `unsafe` 代码的正确性负责,例如在正常代码中不可能遇到的空指针解引用问题在 `unsafe` 中就可能会遇到,我们需要自己来处理好这些类似的问题。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 特定任务的需要
|
|
|
|
#### 特定任务的需要
|
|
|
@ -24,7 +24,7 @@ Rust 的一个主要定位就是系统编程,众所周知,系统编程就是
|
|
|
|
在了解了为何会有 `unsafe` 后,我们再来看看,除了这些必要性,`unsafe` 还能给我们带来哪些超能力。
|
|
|
|
在了解了为何会有 `unsafe` 后,我们再来看看,除了这些必要性,`unsafe` 还能给我们带来哪些超能力。
|
|
|
|
|
|
|
|
|
|
|
|
## unsafe 的超能力
|
|
|
|
## unsafe 的超能力
|
|
|
|
使用 `unsafe` 非常简单,只要用将对应的代码块标记下即可:
|
|
|
|
使用 `unsafe` 非常简单,只需要将对应的代码块标记下即可:
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
fn main() {
|
|
|
|
fn main() {
|
|
|
|
let mut num = 5;
|
|
|
|
let mut num = 5;
|
|
|
@ -57,7 +57,7 @@ fn main() {
|
|
|
|
因此 `unsafe` 能给大家提供的也仅仅是之前的 5 种超能力,在使用这5种能力时,编译器才不会进行内存安全方面的检查,最典型的就是使用**原生指针**(引用和原生指针有很大的区别)。
|
|
|
|
因此 `unsafe` 能给大家提供的也仅仅是之前的 5 种超能力,在使用这5种能力时,编译器才不会进行内存安全方面的检查,最典型的就是使用**原生指针**(引用和原生指针有很大的区别)。
|
|
|
|
|
|
|
|
|
|
|
|
## 谈虎色变?
|
|
|
|
## 谈虎色变?
|
|
|
|
在网上充斥着这样的言论:千万不要使用 `unsafe,因为它不安全,甚至有些库会以没有` unsafe 代码作为噱头来吸引用户。事实上,大可不必,如果按照这个标准,Rust 的标准库也将不复存在!
|
|
|
|
在网上充斥着这样的言论:`千万不要使用 unsafe,因为它不安全`,甚至有些库会以没有 `unsafe` 代码作为噱头来吸引用户。事实上,大可不必,如果按照这个标准,Rust 的标准库也将不复存在!
|
|
|
|
|
|
|
|
|
|
|
|
Rust 中的 `unsafe` 其实没有那么可怕,虽然听上去很不安全,但是实际上 Rust 依然提供了很多机制来帮我们提升了安全性,因此不必像对待 Go 语言的 `unsafe` 那样去畏惧于使用Rust中的 `unsafe` 。
|
|
|
|
Rust 中的 `unsafe` 其实没有那么可怕,虽然听上去很不安全,但是实际上 Rust 依然提供了很多机制来帮我们提升了安全性,因此不必像对待 Go 语言的 `unsafe` 那样去畏惧于使用Rust中的 `unsafe` 。
|
|
|
|
|
|
|
|
|
|
|
@ -70,7 +70,7 @@ Rust 中的 `unsafe` 其实没有那么可怕,虽然听上去很不安全,
|
|
|
|
|
|
|
|
|
|
|
|
即使做到小心谨慎,依然会有出错的可能性,但是 `unsafe` 语句块决定了:就算内存访问出错了,你也能立刻意识到,错误是在 `unsafe` 代码块中,而不花大量时间像无头苍蝇一样去寻找问题所在。
|
|
|
|
即使做到小心谨慎,依然会有出错的可能性,但是 `unsafe` 语句块决定了:就算内存访问出错了,你也能立刻意识到,错误是在 `unsafe` 代码块中,而不花大量时间像无头苍蝇一样去寻找问题所在。
|
|
|
|
|
|
|
|
|
|
|
|
正因为此,写代码时要尽量控制好 `unsafe` 的边界大小,越小的 `unsafe` 越会我们在未来感谢自己当初的选择。
|
|
|
|
正因为此,写代码时要尽量控制好 `unsafe` 的边界大小,越小的 `unsafe` 越会让我们在未来感谢自己当初的选择。
|
|
|
|
|
|
|
|
|
|
|
|
除了控制边界大小,另一个很常用的方式就是在 `unsafe` 代码块外包裹一层 `safe` 的 API,例如一个函数声明为 safe 的,然后在其内部有一块儿是 `unsafe` 代码。
|
|
|
|
除了控制边界大小,另一个很常用的方式就是在 `unsafe` 代码块外包裹一层 `safe` 的 API,例如一个函数声明为 safe 的,然后在其内部有一块儿是 `unsafe` 代码。
|
|
|
|
|
|
|
|
|
|
|
|