update the orgnization of the repo, add rustling -> exercise

pull/122/head
sunface 3 years ago
parent 6da335cfc1
commit 5da1e496a1

@ -2,7 +2,7 @@
authors = ["sunface"]
language = "zh-CN"
title = "Rust语言圣经(Rust教程 Rust Course)"
src = "book-contents"
src = "course-book/contents"
[output.html]
additional-css = ["assets/ferris.css", "assets/theme/2018-edition.css"]

Binary file not shown.

@ -34,5 +34,35 @@ fn foo(x: &str) -> String {
总之栈的分配速度肯定比堆上快但是读取速度往往取决于你的数据能不能放入寄存器或CPU高速缓存。 因此不要仅仅因为堆上性能不如栈这个印象,就总是优先选择栈,导致代码更复杂的实现。
## Box的使用场景
由于`Box`是简单的封装,除了将值存储在堆上外,并没有其它性能上的损耗。而性能和功能往往是鱼和熊掌,因此`Box`相比其它智能指针,功能较为单一,可以在以下场景中使用它:
- 特意的将数据分配在堆上
- 数据较大时,又不想在转移所有权时进行数据拷贝
- 类型的大小在编译期无法确定,但是我们又需要固定大小的类型时
- 特征对象,用于说明对象实现了一个特征,而不是某个特定的类型
以上场景,我们在本章将一一讲解,后面车速较快,请系好安全带。
## 使用`Box<T>`将数据存储在堆上
如果一个变量拥有一个数值`let a = 3`, 那变量`a`必然是存储在栈上的,那如果我们想要`a`的值存储在堆上就需要使用`Boxt<T>`:
```rust
fn main() {
let a = Box::new(3);
println!("a = {}", a); // a = 3
// 下面一行代码将报错
// let b = a + 1; // cannot add `{integer}` to `Box<{integer}>`
}
```
这样就可以创建一个智能指针指向了存储在堆上的`5`,并且`a`持有了该指针。在本章的引言中,我们提到了智能指针往往都实现了`Deref`和`Drop`特征,因此:
- `println!`可以正常打印出`a`的值,是因为它隐式的调用了`Deref`对智能指针`a`进行了解引用
- 最后一行代码`let b = a + 1`报错,是因为在表达式中,我们无法自动隐式的执行`Deref`解引用操作, 你需要使用`*`操作符`let b = *a + 1`,来显式的进行解引用
- `a`持有的智能指针将在作用结束(`main`函数结束)时,被释放掉,这是因为`Box<T>`实现了`Drop`特征
以上的例子在实际代码中其实很少会存在因为将一个简单的值分配到堆上并没有太大的意义。将其分配在栈上由于寄存器、CPU缓存的原因它的性能将更好而且代码可读性也更好。
## Box::leak

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save