Merge pull request #1159 from gfzum/fix-typo

Fix 一些标点的小改动
pull/1171/head
Sunface 2 years ago committed by GitHub
commit e451fd2028
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,7 +8,7 @@ Rust 中哈希类型(哈希映射)为 `HashMap<K,V>`,在其它语言中,
跟创建动态数组 `Vec` 的方法类似,可以使用 `new` 方法来创建 `HashMap`,然后通过 `insert` 方法插入键值对。
#### 使用 new 方法创建
### 使用 new 方法创建
```rust
use std::collections::HashMap;
@ -28,9 +28,9 @@ my_gems.insert("河边捡的误以为是宝石的破石头", 18);
所有的集合类型都是动态的,意味着它们没有固定的内存大小,因此它们底层的数据都存储在内存堆上,然后通过一个存储在栈中的引用类型来访问。同时,跟其它集合类型一致,`HashMap` 也是内聚性的,即所有的 `K` 必须拥有同样的类型,`V` 也是如此。
> 跟 `Vec` 一样,如果预先知道要存储的 `KV` 对个数,可以使用 `HashMap::with_capacity(capacity)` 创建指定大小的 `HashMap`,避免频繁的内存分配和拷贝,提升性能
> 跟 `Vec` 一样,如果预先知道要存储的 `KV` 对个数,可以使用 `HashMap::with_capacity(capacity)` 创建指定大小的 `HashMap`,避免频繁的内存分配和拷贝,提升性能
#### 使用迭代器和 collect 方法创建
### 使用迭代器和 collect 方法创建
在实际使用中,不是所有的场景都能 `new` 一个哈希表后,然后悠哉悠哉的依次插入对应的键值对,而是可能会从另外一个数据结构中,获取到对应的数据,最终生成 `HashMap`
@ -282,7 +282,7 @@ println!("{:?}", map);
先来设想下,如果要实现 `Key``Value` 的一一对应,是不是意味着我们要能比较两个 `Key` 的相等性?例如 "a" 和 "b"1 和 2当这些类型做 `Key` 且能比较时,可以很容易知道 `1` 对应的值不会错误的映射到 `2` 上,因为 `1` 不等于 `2`。因此,一个类型能否作为 `Key` 的关键就是是否能进行相等比较,或者说该类型是否实现了 `std::cmp::Eq` 特征。
> f32 和 f64 浮点数,没有实现 `std::cmp::Eq` 特征,因此不可以用作 `HashMap``Key`
> f32 和 f64 浮点数,没有实现 `std::cmp::Eq` 特征,因此不可以用作 `HashMap``Key`
好了,理解完这个,再来设想一点,若一个复杂点的类型作为 `Key`,那怎么在底层对它进行存储,怎么使用它进行查询和比较? 是不是很棘手?好在我们有哈希函数:通过它把 `Key` 计算后映射为哈希值,然后使用该哈希值来进行存储、查询、比较等操作。
@ -307,7 +307,7 @@ hash.insert(42, "the answer");
assert_eq!(hash.get(&42), Some(&"the answer"));
```
> 目前,`HashMap` 使用的哈希函数是 `SipHash`,它的性能不是很高,但是安全性很高。`SipHash` 在中等大小的 `Key` 上,性能相当不错,但是对于小型的 `Key` (例如整数)或者大型 `Key` (例如字符串)来说,性能还是不够好。若你需要极致性能,例如实现算法,可以考虑这个库:[ahash](https://github.com/tkaitchuck/ahash)
> 目前,`HashMap` 使用的哈希函数是 `SipHash`,它的性能不是很高,但是安全性很高。`SipHash` 在中等大小的 `Key` 上,性能相当不错,但是对于小型的 `Key` (例如整数)或者大型 `Key` (例如字符串)来说,性能还是不够好。若你需要极致性能,例如实现算法,可以考虑这个库:[ahash](https://github.com/tkaitchuck/ahash)
最后,如果你想要了解 `HashMap` 更多的用法,请参见本书的标准库解析章节:[HashMap 常用方法](https://course.rs/std/hashmap.html)

@ -85,7 +85,7 @@ match v.get(2) {
和其它语言一样,集合类型的索引下标都是从 `0` 开始,`&v[2]` 表示借用 `v` 中的第三个元素,最终会获得该元素的引用。而 `v.get(2)` 也是访问第三个元素,但是有所不同的是,它返回了 `Option<&T>`,因此还需要额外的 `match` 来匹配解构出具体的值。
> 细心的同学会注意到这里使用了两种格式化输出的方式,其中第一种我们在之前已经见过,而第二种是后续新版本中引入的写法,也是更推荐的用法,具体介绍请参见[格式化输出章节](https://course.rs/basic/formatted-output.html)
> 细心的同学会注意到这里使用了两种格式化输出的方式,其中第一种我们在之前已经见过,而第二种是后续新版本中引入的写法,也是更推荐的用法,具体介绍请参见[格式化输出章节](https://course.rs/basic/formatted-output.html)
### 下标索引与 `.get` 的区别
@ -148,7 +148,7 @@ error: could not compile `collections` due to previous error
其实想想,**在长大之后,我们感激人生路上遇到过的严师益友,正是因为他们,我们才在正确的道路上不断前行,虽然在那个时候,并不能理解他们**,而 Rust 就如那个良师益友,它不断的在纠正我们不好的编程习惯,直到某一天,你发现自己能写出一次性通过的漂亮代码时,就能明白它的良苦用心。
> 若读者想要更深入的了解 `Vec<T>`,可以看看[Rustonomicon](https://nomicon.purewhite.io/vec/vec.html),其中从零手撸一个动态数组,非常适合深入学习
> 若读者想要更深入的了解 `Vec<T>`,可以看看[Rustonomicon](https://nomicon.purewhite.io/vec/vec.html),其中从零手撸一个动态数组,非常适合深入学习
## 迭代遍历 Vector 中的元素

@ -619,7 +619,7 @@ let s: &'static str = "我没啥优点,就是活得久,嘿嘿";
- 生命周期 `'static` 意味着能和程序活得一样久,例如字符串字面量和特征对象
- 实在遇到解决不了的生命周期标注问题,可以尝试 `T: 'static`,有时候它会给你奇迹
> 事实上,关于 `'static`, 有两种用法: `&'static``T: 'static`,详细内容请参见[此处](https://course.rs/advance/lifetime/static.html)
> 事实上,关于 `'static`, 有两种用法: `&'static``T: 'static`,详细内容请参见[此处](https://course.rs/advance/lifetime/static.html)
## 一个复杂例子: 泛型、特征约束

@ -220,7 +220,7 @@ impl Rectangle {
}
```
> Rust 中有一个约定俗成的规则,使用 `new` 来作为构造器的名称出于设计上的考虑Rust 特地没有用 `new` 作为关键字
> Rust 中有一个约定俗成的规则,使用 `new` 来作为构造器的名称出于设计上的考虑Rust 特地没有用 `new` 作为关键字
因为是函数,所以不能用 `.` 的方式来调用,我们需要用 `::` 来调用,例如 `let sq = Rectangle::new(3, 3);`。这个方法位于结构体的命名空间中:`::` 语法用于关联函数和模块创建的命名空间。

@ -110,7 +110,7 @@ pub struct Screen {
可以通过 `&` 引用或者 `Box<T>` 智能指针的方式来创建特征对象。
> `Box<T>` 在后面章节会[详细讲解](https://course.rs/advance/smart-pointer/box.html),大家现在把它当成一个引用即可,只不过它包裹的值会被强制分配在堆上
> `Box<T>` 在后面章节会[详细讲解](https://course.rs/advance/smart-pointer/box.html),大家现在把它当成一个引用即可,只不过它包裹的值会被强制分配在堆上
```rust

@ -1,6 +1,6 @@
# 特征 Trait
如果我们想定义一个文件系统,那么把该系统跟底层存储解耦是很重要的。文件操作主要包含四个:`open` 、`write`、`read`、`close`这些操作可以发生在硬盘可以发生在内存还可以发生在网络IO甚至(...我实在编不下去了,大家来帮帮我)。总之如果你要为每一种情况都单独实现一套代码,那这种实现将过于繁杂,而且也没那个必要。
如果我们想定义一个文件系统,那么把该系统跟底层存储解耦是很重要的。文件操作主要包含四个:`open` 、`write`、`read`、`close`这些操作可以发生在硬盘可以发生在内存还可以发生在网络IO甚至...我实在编不下去了,大家来帮帮我)。总之如果你要为每一种情况都单独实现一套代码,那这种实现将过于繁杂,而且也没那个必要。
要解决上述问题,需要把这些行为抽象出来,就要使用 Rust 中的特征 `trait` 概念。可能你是第一次听说这个名词,但是不要怕,如果学过其他语言,那么大概率你听说过接口,没错,特征跟接口很类似。

Loading…
Cancel
Save