Merge branch 'main' into patch-2

pull/509/head
Fanyjie 3 years ago committed by GitHub
commit df8eb78241
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,9 +4,11 @@
- 官方: [https://course.rs](https://course.rs)
- 知乎: [支持章节内目录跳转,很好用!](https://www.zhihu.com/column/c_1452781034895446017)
> 学了 Rust 语法后迷茫了?来试试 [Rust By Practice](https://github.com/sunface/rust-by-practice),它是本书的配套练习题和实践,覆盖了 easy to hard 各个难度,满足你的所有需求。
> 学习 Rust 光看书不够,精心设计的习题和项目实践可以让你事半功倍。[Rust By Practice](https://github.com/sunface/rust-by-practice) 是本书的配套习题和实践,覆盖了 easy to hard 各个难度,满足大家对 Rust 的所有期待。
>
> [Rust 语言周刊](https://github.com/sunface/rust-weekly),每周一发布,精选过去一周的技术文章、业界新闻、开源项目和 Rust 语言动态。
>
> [Rust 语言周刊](https://github.com/sunface/rust-weekly),每周一发布,这里有精选的开源项目、新闻、技术文章和 Rust 语言更新等内容栏目。
> Rust 优秀项目很多,如何在茫茫码海中与它们相遇?相比 Awesome Rust [Fancy Rust](https://github.com/sunface/fancy-rust) 能带给你全新的体验和选择
### 教程简介

@ -5,7 +5,7 @@
可能也有不少人第一次听说自引用结构体,那咱们先来看看它们长啥样。
```rust
struct RefWithinMe<'a> {
struct SelfRef<'a> {
value: String,
// 该引用指向上面的value

@ -92,10 +92,10 @@ let slice = &s[..];
> let s = "中国人";
> let a = &s[0..2];
> println!("{}",a);
> ```
>```
>
> 因为我们只取 `s` 字符串的前两个字节,但是本例中每个汉字占用三个字节,因此没有落在边界处,也就是连 `中` 字都取不完整,此时程序会直接崩溃退出,如果改成 `&s[0..3]`,则可以正常通过编译。
> 因此,当你需要对字符串做切片索引操作时,需要格外小心这一点, 关于该如何操作 UTF-8 字符串,参见[这里](#操作-UTF8-字符串)
> 因此,当你需要对字符串做切片索引操作时,需要格外小心这一点, 关于该如何操作 UTF-8 字符串,参见[这里](#操作-utf8-字符串)
字符串切片的类型标识是 `&str`,因此我们可以这样声明一个函数,输入 `String` 类型,返回它的切片: `fn first_word(s: &String) -> &str `

@ -49,4 +49,4 @@ fn main() {
有几点可以留意下:
- 字符串使用双引号 `""` 而不是单引号 `''`Rust 中单引号是留给单个字符类型(`char`)使用的
- Rust 使用 `{}` 来作为格式化输出占位符,其它语言可能使用的是 `%s``%d``%p` 等,由于 `println!` 会自动推导出具体的类型, 因此无需手动指定
- Rust 使用 `{}` 来作为格式化输出占位符,其它语言可能使用的是 `%s``%d``%p` 等,由于 `println!` 会自动推导出具体的类型因此无需手动指定

@ -20,7 +20,7 @@
在其它语言中,我们用 `var a = "hello world"` 的方式给 `a` 赋值,也就是把等式右边的 `"hello world"` 字符串赋值给变量 `a` ,而在 Rust 中,我们这样写: `let a = "hello world"` ,同时给这个过程起了另一个名字:**变量绑定**。
为何不用赋值而用绑定呢(其实你也可以称之为赋值,但是绑定的含义更清晰准确)?这里就涉及 Rust 最核心的原则——**所有权**,简单来讲,任何内存对象都是有主人的,而且一般情况下完全属于它的主人,绑定就是把这个对象绑定给一个变量,让这个变量成为它的主人(聪明的读者应该能猜到,在这种情况下,该对象之前的主人就会丧失对该对象的所有权),像极了我们的现实世界,不是吗?
为何不用赋值而用绑定呢(其实你也可以称之为赋值,但是绑定的含义更清晰准确)?这里就涉及 Rust 最核心的原则——**所有权**,简单来讲,任何内存对象都是有主人的,而且一般情况下完全属于它的主人,绑定就是把这个对象绑定给一个变量,让这个变量成为它的主人聪明的读者应该能猜到,在这种情况下,该对象之前的主人就会丧失对该对象的所有权,像极了我们的现实世界,不是吗?
至于为何要采用所有权这种复杂的东东,先别急,等时机合适,我们会为你详细道来。
@ -93,9 +93,9 @@ The value of x is: 5
The value of x is: 6
```
选择可变还是不可变,更多的还是取决于你的使用场景,例如不可变可以带来安全性,但是丧失了灵活性和性能(如果你要改变,就要重新创建一个新的变量,这里涉及到内存对象的再分配)。而可变变量最大的好处就是使用上的灵活性和性能上的提升。
选择可变还是不可变,更多的还是取决于你的使用场景,例如不可变可以带来安全性,但是丧失了灵活性和性能(如果你要改变,就要重新创建一个新的变量,这里涉及到内存对象的再分配)。而可变变量最大的好处就是使用上的灵活性和性能上的提升。
例如,在使用大型数据结构或者热点代码路径(被大量频繁调用)的情形下,在同一内存位置更新实例可能比复制并返回新分配的实例要更快。使用较小的数据结构时,通常创建新的实例并以更具函数式的风格来编写程序,可能会更容易理解,所以值得以较低的性能开销来确保代码清晰。
例如,在使用大型数据结构或者热点代码路径(被大量频繁调用)的情形下,在同一内存位置更新实例可能比复制并返回新分配的实例要更快。使用较小的数据结构时,通常创建新的实例并以更具函数式的风格来编写程序,可能会更容易理解,所以值得以较低的性能开销来确保代码清晰。
### 变量解构

@ -30,7 +30,7 @@ Rust 跟其它语言不一样,你无法看了一遍语法,然后就能上手
## 千万别从链表或图开始练手
CS 课程中我们会学习大量的常用数据结构和算法,因此大家都养成了一种好习惯:学习一门新语言,先用它写个链表或图试试。
CSComputer Science计算机科学课程中我们会学习大量的常用数据结构和算法,因此大家都养成了一种好习惯:学习一门新语言,先用它写个链表或图试试。
我的天,在 Rust 中**千万别这么干**,你是在扼杀自己之前的努力!因为不像其它语言,链表在 Rust 中简直是地狱一般的难度,我见过太多英雄好汉难过链表关,最终黯然退幕。我不希望正在阅读此文的你也成为其中一个 :

Loading…
Cancel
Save