mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2024-12-26 12:50:42 +08:00
Update Ch15
This commit is contained in:
parent
b539031b11
commit
426a335ec1
@ -774,13 +774,14 @@ $ cargo run
|
||||
- 在任何给定时间,咱们都可以有着 *要么* (而非同时) 一个可变引用,要么任意数量的不可变引用;
|
||||
- 引用必须始终有效。
|
||||
|
||||
在引用及 `Box<T>` 之下,这些借用规则的那些不变性,在编译时被强制检查(with references and `Box<T>`, the borrowing rules' invariants are enforced at compile time)。而在 `RefCell<T>` 之下,这些不变性是在 *运行时,runtime*,被强制检查的。对于引用,在破坏这些规则时,就会得到编译时错误。而对于 `RecCell<T>`,在破坏这些规则时,程序就会终止运行并退出。
|
||||
|
||||
在编译时检查借用规则的好处,就是那些错误会在开发过程中被及时捕获到,而因为全部代码分析都是提前完成的,因此在运行时性能上没有影响。由于这些原因,在编译时检查借用规则,即是大多数情形中的最佳实践,也正是 Rust 作为默认项的原因。
|
||||
对于引用与 `Box<T>`,借用规则的不变性,the borrowing rules' invariants, 是在编译时强制执行的。对于 `RefCell<T>`,这些不变性则是在运行时强制执行的。对于引用,如果咱们破坏了这些规则,咱们会得到编译器报错。而在 `RefCell<T>` 中,如果咱们破坏了这些规则,咱们的程序将终止运行。
|
||||
|
||||
相反在运行时检查借用规则的优势,在于这个时候明确的内存安全场景是被允许的,这些场景中,他们原本是不被编译时借用规则检查所允许。一些静态分析,好比 Rust 的编译器,本质上是保守的。代码的一些属性,都是不可能通过分析代码侦测到的:其中最有名的示例,便是图灵停机问题,the Halting Problem,这个问题超出了本书的范围,但是个要研究的有趣话题。
|
||||
在编译时检查借用规则的好处是在开发过程中会更早地发现错误,而且对运行时性能没有影响,因为所有分析都是事先完成的。由于这些原因,在大多数情况下,在编译时检查借用规则是最好的选择,这就是为什么这是 Rust 的默认设置。
|
||||
|
||||
由于某些分析不可能进行,因此在 Rust 编译器无法确定代码,在所有权规则下会编译时,他就会拒绝某个正确的程序;从这方面讲,他就是保守的了。假如 Rust 编译器接受不正确的程序,那么用户将无法信任 Rust 所做出的那些保证。然而,若 Rust 拒绝某个正确程序,那么编程者就将感到不便,却又不会发生什么灾难性的事情。在咱们确定咱们的代码遵循了借用规则,只不过编译器无法理解并确保那一点时,`RefCell<T>` 类型便是有用的了。
|
||||
相反,在运行时检查借用规则的优点是允许某些内存安全的场景,而编译时检查则不会允许这些场景。与 Rust 编译器一样,静态分析,static analysis,本质上是保守的。代码的某些属性无法通过分析代码来检测:最著名的例子是停机问题,the Halting Problem, 它超出了本书的范围,但却是一个值得研究的有趣主题。
|
||||
|
||||
由于某些分析是不可行的,那么如果 Rust 编译器不能确定代码符合所有权规则,他可能会拒绝某个正确的程序;从这方面讲,他是保守的。如果 Rust 编译器接受了错误的程序,用户就无法相信 Rust 做出的保证。然而,如果 Rust 拒绝了某个正确的程序,编程者会感到不便,但又不会发生什么灾难性的事情。在咱们确定咱们的代码遵循借用规则,而编译器无法理解和保证时,`RefCell<T>` 类型就很有用。
|
||||
|
||||
与 `Rc<T>` 类似,`RefCell<T>` 仅用于一些单线程场景中,并在咱们尝试将其用于多线程语境中时,将给到一个编译时报错。在第 16 章将讲到怎样在多线程的程序中,获得 `RefCell<T>` 的功能。
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user