Update Ch15

This commit is contained in:
Unisko PENG 2023-05-12 15:54:58 +08:00
parent 4b581b9e85
commit 93088148c8

View File

@ -945,7 +945,7 @@ warning: build failed, waiting for other jobs to finish...
`RefCell<T>` 会记录当前有多少个 `Ref<T>``RefMut<T>` 灵巧指针是活动的。每次我们调用 `borrow``RefCell<T>` 都会增加他的计数,即有多少个不可变借用是活动的。当一个 `Ref<T>` 值超出作用域时,不可变借用的计数就会减少一个。就像编译时的借用规则一样,`RefCell<T>` 允许我们在任何时候有许多不可变借用或一个可变的借用。
在咱们尝试违反这些规则时,与之前在引用下得到编译器报错相反`RefCell<T>` 的实现将在运行时终止运行。下面清单 15-23 给出了清单 15-22 中那个 `send` 实现的修改版本。其中故意尝试创建出统一作用域的两个活动可变借用,来演示 `RefCell<T>`在运行时阻止咱们这样做。
在咱们尝试违反这些规则时,与在引用下咱们会得到编译器报错不同`RefCell<T>` 的实现将在运行时终止运行。下面清单 15-23 给出了清单 15-22 中那个 `send` 实现的修改。咱们故意为同一作用域创建了两个可变借用,以演示 `RefCell<T>` 在运行时阻止咱们这样做。
文件名:`src/lib.rs`
@ -961,12 +961,12 @@ warning: build failed, waiting for other jobs to finish...
}
```
*清单 15-23创建出同一作用域中的两个可变引用,来发现 `RefCell<T>`终止运行*
*清单 15-23在同一作用域中创建两个可变引用,以发现 `RefCell<T>`终止运行*
这里创建了返回自 `borrow_mut` 的一个灵巧指针 `RefCell<T>` 的变量 `borrow_one`。随后这里以同样方式创建了变量 `borrow_two` 中的另一可变借用。这就在同一作用域中构造了两个可变引用,而这是不运行的。在咱们运行这个库的测试时,清单 15-23 中的代码将不带任何报错地编译,但测试将失败:
我们为从 `borrow_mut` 返回的 `RefMut<T>` 智能指针创建了一个变量 `one_borrow`。然后我们以同样的方式在变量 `two_borrow` 中创建了另一个可变的借用。这就在同一作用域中产生了两个可变引用,这是不允许的。当我们运行咱们库的测试时,清单 15-23 中的代码将被不带任何报错地编译,但测试将失败:
```console
$ cargo test  101 ✘  
$ cargo test
Compiling limit_tracker v0.1.0 (/home/peng/rust-lang/limit_tracker)
Finished test [unoptimized + debuginfo] target(s) in 0.46s
Running unittests src/lib.rs (target/debug/deps/limit_tracker-98d6159d1b15eb72)
@ -991,7 +991,7 @@ error: test failed, to rerun pass `--lib`
请注意该代码是以消息 `already borrowed: BorrowMutError` 终止运行的。这正是 `RefCell<T>` 处理运行时违反借用规则的方式。
选择在运行时,而非编译时捕获借用报错,正如这里所做的那样,就意味着咱们潜在地会在程序开发过程中晚一点的时候,发现代码中的错误:那么就可能在直到代码部署到生产环境时,也没有发现这些错误。同时,咱们的代码还会因在运行时,而非编译时保持对那些借用的追踪,而遭受由此导致的性能代价。然而,`RefCell<T>` 的使用,令到在只允许使用一些不可变值的上下文中,编写出正使用着的,可对自身加以修改,从而跟踪其所见到的那些消息的模拟对象成为可能。咱们可在权衡了其弊端,及相交常规引用所能提供到的更多功能后,合理使用 `RefCell<T>` 这种灵巧指针
选择在运行时而不是编译时捕获借用错误,正如我们在这里所做的那样,意味着咱们可能会在开发过程后期,才发现代码中的错误:可能直到咱们的代码部署到生产环境中,才发现。此外,由于在运行时而不是编译时记录借用,咱们的代码会招致小的运行时性能损失。但是,使用 `RefCell<T>` 可以编写出模拟对象,该对象可以修改自身来记录咱们在仅允许不可变值的上下文中使用他时看到的消息。咱们可以使用 `RefCell<T>`,尽管他需要权衡取舍以获得比常规引用所提供的更多功能
### 通过结合 `Rc<T>``RefCell<T>`,实现可变数据的多个所有者