Update Ch15

This commit is contained in:
Peng Hailin, 2023-05-07 16:18:29 +08:00
parent 83433a65d5
commit 63353ee8e4

View File

@ -168,11 +168,11 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` repre
| ++++ +
```
在此建议中,“间接性的东西indirection” 表示与其直接存储某个值,这里应该将这个数据结构,修改为通过存储指向到值的指针,间接地存储那个值。
在此建议中,“间接indirection” 意味着我们不应直接存储一个值,而应该改变数据结构,通过存储一个指向该值的指针,间接存储该值。
由于 `Box<T>` 是个指针Rust 就始终清楚一个 `Box<T>` 需要多少内存空间:指针的大小,不会因其指向数据的空间数量而变化。这就意味着这里可把一个 `Box<T>`,而不是直接把另一个 `List`,放在那个 `Cons` 变种里头。这个 `Box<T>` 将指向将位于内存堆上,而非在那个 `Cons` 内部的下一 `List`。从概念上讲,这里仍会有以包含其他列表的一些列表方式,创建出的一个列表,但现在这种实现看起来更像是把那些列表挨个放置,而不是一个列表在另一列表内部
由于 `Box<T>` 是个指针Rust 总是知道 `Box<T>` 需要多少内存空间:指针的大小不会根据他指向的数据量而变化。这意味着咱们可以在 `Cons` 变种里放入一个 `Box<T>`,而不是直接放入另一个 `List` 值。`Box<T>` 将指向下一个 `List` 值,他将在内存堆上而不是在 `Cons` 变种内。从概念上讲,咱们仍然有一个列表,用持有其他列表的列表来创建,但现在这种实现更像是把列表项目放在彼此的旁边,而不是放在彼此的里面
这里可将清单 15-2 中那个 `List` 枚举的定义,与清单 15-3 中该 `List` 的用法,修改为下面清单 15-5 中的代码,这就会编译了:
咱们可以把清单 15-2 中 `List` 枚举的定义和清单 15-3 中 `List` 的用法,改为下面清单 15-5 中的代码,这样就可以编译了:
文件名:`src/main.rs`
@ -192,13 +192,13 @@ fn main() {
}
```
*清单 15-5为有着已知大小而使用了 `Box<T>``List` 定义*
*清单 15-5使用Box<T>的List的定义以便有已知的大小*
其中的 `Cons` 变种,需要一个 `i32` 的大小加上存储那个匣子指针数据的内存空间。那个 `Nil` 变种未存储值,因此他需要的空间,要少于 `Cons` 变种。现在咱们就指定任何 `List` 值,都会占用一个 `i32` 的大小加上一个匣子指针数据的大小了。通过使用匣子,咱们就破解了那个无限的、递归的链条,因此编译器就可以计算出,他存储一个 `List` 值所需的内存大小。下图 15-2 显示了那个 `Cons` 现在看起来的样子:
`Cons` 变种需要一个 `i32` 的大小,加上存储匣子指针数据的内存空间。`Nil` 变种不存储存储任何值,所以他需要的空间比 `Cons` 变种少。咱们现在知道,任何 `List` 值都会占用一个 `i32` 的大小,加上一个匣子的指针数据的大小。通过使用匣子,咱们已经破解了无限的递归链,因此编译器可以计算出存储 `List` 值所需的内存大小。下图 15-2 显示了 `Cons` 变种现在的样子:
![由于 `Cons` 保存了一个 `Box` 而不在是无限大小的 `List`](images/15-02.svg)
*图 15-02由于 `Cons` 保存了一个 `Box` 而不在是无限大小的 `List`*
*图 15-02不在是无限大小的 `List`,因为 `Cons` 持有着一个 `Box`*
匣子数据结构,仅提供了这种间接性的东西与内存堆方面的空间分配;他们不具备像是将在其他灵巧指针类型下,所发现的那些其他特别能力。匣子类型也不会有这些特别能力所招致的性能开销,因此他们在像是构造列表这种,仅需间接性特性的情形下,会是有用的。在第 17 章,还将会检视匣子类型的更多用例。