pull/275/head
sunface 3 years ago
commit ce8283faaa

@ -17,7 +17,7 @@
- **OS线程**, 它最简单,也无需改变任何编程模型(业务/代码逻辑),因此非常适合作为语言的原生并发模型,我们在[多线程章节](../advnce/../advance/concurrency-with-threads/concurrency-parallelism.md)也提到过Rust 就选择了原生支持线程级的并发编程。但是,这种模型也有缺点,例如线程间的同步将变得更加困难,线程间的上下文切换损耗较大。使用线程池在一定程度上可以提升性能,但是对于 IO 密集的场景来说,线程池还是不够看。 - **OS线程**, 它最简单,也无需改变任何编程模型(业务/代码逻辑),因此非常适合作为语言的原生并发模型,我们在[多线程章节](../advnce/../advance/concurrency-with-threads/concurrency-parallelism.md)也提到过Rust 就选择了原生支持线程级的并发编程。但是,这种模型也有缺点,例如线程间的同步将变得更加困难,线程间的上下文切换损耗较大。使用线程池在一定程度上可以提升性能,但是对于 IO 密集的场景来说,线程池还是不够看。
- **事件驱动(Event driven)**, 这个名词你可能比较陌生,如果说事件驱动常常跟回调( Callback )一起使用,相信大家就恍然大悟了。这种模型性能相当的好,但最大的问题就是存在回调地狱的风险:非线性的控制流和结果处理导致了数据流向和错误传播变得难以掌控,还会导致代码维护性和可读性的大幅降低,大名鼎鼎的 JS 曾经就存在回调地狱。 - **事件驱动(Event driven)**, 这个名词你可能比较陌生,如果说事件驱动常常跟回调( Callback )一起使用,相信大家就恍然大悟了。这种模型性能相当的好,但最大的问题就是存在回调地狱的风险:非线性的控制流和结果处理导致了数据流向和错误传播变得难以掌控,还会导致代码维护性和可读性的大幅降低,大名鼎鼎的 JS 曾经就存在回调地狱。
- **协程(Coroutines)**可能是目前最火的并发模型,`Go` 语言的协程设计就非常优秀,这也是 `Go` 语言能够迅速火遍全球的杀手锏之一。协程跟线程类似,无需改变编程模型,同时,它也跟 `async` 类似,可以支持大量的任务并发运行。但协程抽象层次过高,导致用户无法接触到底层的细节,这对于系统编程语言和自定义异步运行时是难以接受的 - **协程(Coroutines)** 可能是目前最火的并发模型,`Go` 语言的协程设计就非常优秀,这也是 `Go` 语言能够迅速火遍全球的杀手锏之一。协程跟线程类似,无需改变编程模型,同时,它也跟 `async` 类似,可以支持大量的任务并发运行。但协程抽象层次过高,导致用户无法接触到底层的细节,这对于系统编程语言和自定义异步运行时是难以接受的
- **actor模型**是erlang的杀手锏之一它将所有并发计算分割成一个一个单元这些单元被称为 `actor` , 单元之间通过消息传递的方式进行通信和数据传递,跟分布式系统的设计理念非常相像。由于 `actor` 模型跟现实很贴近,因此它相对来说更容易实现,但是一旦遇到流控制、失败重试等场景时,就会变得不太好用 - **actor模型**是erlang的杀手锏之一它将所有并发计算分割成一个一个单元这些单元被称为 `actor` , 单元之间通过消息传递的方式进行通信和数据传递,跟分布式系统的设计理念非常相像。由于 `actor` 模型跟现实很贴近,因此它相对来说更容易实现,但是一旦遇到流控制、失败重试等场景时,就会变得不太好用
- **async/await** 该模型性能高,还能支持底层编程,同时又像线程和协程那样无需过多的改变编程模型,但有得必有失,`async` 模型的问题就是内部实现机制过于复杂,对于用户来说,理解和使用起来也没有线程和协程简单,好在前者的复杂性开发者们已经帮我们封装好,而理解和使用起来不够简单,正是本章试图解决的问题。 - **async/await** 该模型性能高,还能支持底层编程,同时又像线程和协程那样无需过多的改变编程模型,但有得必有失,`async` 模型的问题就是内部实现机制过于复杂,对于用户来说,理解和使用起来也没有线程和协程简单,好在前者的复杂性开发者们已经帮我们封装好,而理解和使用起来不够简单,正是本章试图解决的问题。

@ -16,7 +16,7 @@ fn main() {
} }
``` ```
如果大家从部分陈旧的语言来可能会大喊一声这XX叫字符是的在Rust语言中这些都是字符Rust的字符不仅仅是`ASCII`,所有的`Unicode`值都可以作为Rust字符包括中文/日文/韩文emoji表情等等,都是合法的字符类型。`Unicode` 值的范围从 `U+0000~U+D7FF``U+E000~U+10FFFF`。不过“字符”并不是 `Unicode` 中的一个概念,所以人在直觉上对“字符”的理解和 Rust 的字符概念并不一致。 如果大家从部分陈旧的语言来可能会大喊一声这XX叫字符是的在Rust语言中这些都是字符Rust的字符不仅仅是`ASCII`,所有的`Unicode`值都可以作为Rust字符包括单个的中文、日文、韩文、emoji表情符号等等,都是合法的字符类型。`Unicode` 值的范围从 `U+0000~U+D7FF``U+E000~U+10FFFF`。不过“字符”并不是 `Unicode` 中的一个概念,所以人在直觉上对“字符”的理解和 Rust 的字符概念并不一致。
由于`Unicode`都是4个字节编码因此字符类型也是占用4个字节 由于`Unicode`都是4个字节编码因此字符类型也是占用4个字节
```rust ```rust
@ -57,7 +57,7 @@ fn main() {
## 元类型 ## 元类型
元类型就是`()`,对,你没看错,就是`()`,唯一的值也是`()`可能读者读到这里就不愿意了,你也太敷衍了吧,管这叫类型? 元类型就是`()`,对,你没看错,就是`()`,唯一的值也是`()`一些读者读到这里可能就不愿意了,你也太敷衍了吧,管这叫类型?
只能说,再不起眼的东西,都有其用途,在目前为止的学习过程中,大家已经看到过很多次`fn main()`函数的使用吧?那么这个函数返回什么呢? 只能说,再不起眼的东西,都有其用途,在目前为止的学习过程中,大家已经看到过很多次`fn main()`函数的使用吧?那么这个函数返回什么呢?

@ -85,7 +85,7 @@ fn main() {
`x + 5`是一条表达式,求值后,返回一个值,因为它是函数的最后一行,因此该表达式的值也是函数的返回值。 `x + 5`是一条表达式,求值后,返回一个值,因为它是函数的最后一行,因此该表达式的值也是函数的返回值。
再来看两个重点: 再来看两个重点:
1. `let x = add_five(5)`,说明我们用一个函数的返回值来初始化`x`变量因此侧面说明了在Rust中函数也是表达式 这种写法等同于`let x = 5 + 5;` 1. `let x = plus_five(5)`,说明我们用一个函数的返回值来初始化`x`变量因此侧面说明了在Rust中函数也是表达式 这种写法等同于`let x = 5 + 5;`
2. `x + 5`没有分号,因为它是一条表达式,这个在上一节中我们也有详细介绍 2. `x + 5`没有分号,因为它是一条表达式,这个在上一节中我们也有详细介绍
再来看一段代码,同时使用`return`和表达式作为返回值: 再来看一段代码,同时使用`return`和表达式作为返回值:

@ -26,7 +26,7 @@ let heart = PokerSuit::Hearts;
let diamond = PokerSuit::Diamonds; let diamond = PokerSuit::Diamonds;
``` ```
我们通过`::`操作符来访问`PokerSuit`下的具体成员,从代码可以清晰看出,`heart`和`diamond`都是`PkerSuit`枚举类型的,接着可以定义一个函数来使用它们: 我们通过`::`操作符来访问`PokerSuit`下的具体成员,从代码可以清晰看出,`heart`和`diamond`都是`PokerSuit`枚举类型的,接着可以定义一个函数来使用它们:
```rust ```rust
fn main() { fn main() {
let heart = PokerSuit::Hearts; let heart = PokerSuit::Hearts;

@ -29,7 +29,7 @@ OK这样就已经完成 Rust 安装啦。
### 安装 C 语言编译器:(非必需) ### 安装 C 语言编译器:(非必需)
Rust 对运行环境和 Go 语言很像几乎所有环境都可以无需安装任何依赖直接运行。但是Rust 会依赖 `libc` 和链接器 `linker`。所以如果遇到了提示链接器无法执行的错误,你需要再手动安装一个 C 语言编译器: Rust 对运行环境的依赖和 Go 语言很像几乎所有环境都可以无需安装任何依赖直接运行。但是Rust 会依赖 `libc` 和链接器 `linker`。所以如果遇到了提示链接器无法执行的错误,你需要再手动安装一个 C 语言编译器:
**MacOS 下:** **MacOS 下:**

@ -1,11 +1,10 @@
# Generics # 泛型
Generics is the topic of generalizing types and functionalities to broader cases. 泛型的主旨是把类型和函数泛化到多种情况。
This is extremely useful for reducing code duplication in many ways, but can call for rather involving syntax. 这在很多方面有助于减少重复代码,但也可能需要为此使用相当多的语法。
Namely, being generic requires taking great care to specify over which types a generic type is actually considered valid. 也就是说,使用泛型的话则需要小心谨慎地标明泛型适用于哪些类型。
The simplest and most common use of generics is for type parameters.
## Further information ## 更多信息
- [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html) - [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html)
- [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html) - [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)

@ -1,17 +1,33 @@
# Option # Option
Type Option represents an optional value: every Option is either Some and contains a value, or None, and does not. Option 类型代表可选的值:每个 Option 要么是 Some ,包含一个值;要么是 None ,表示空值。
Option types are very common in Rust code, as they have a number of uses: Option 在 Rust 代码中十分常见,因为它有许多用途:
- Initial values - 初始值
- Return values for functions that are not defined over their entire input range (partial functions) - 输入值不符合定义的情况下作为函数的返回值(部分函数)。
- Return value for otherwise reporting simple errors, where None is returned on error - 返回 None 作为简单错误的返回值
- Optional struct fields - 可选的结构字段
- Struct fields that can be loaned or "taken" - 可以借用或 "取走" 的结构字段(的值)
- Optional function arguments - 可选的函数参数
- Nullable pointers - 空指针
- Swapping things out of difficult situations - 在某些情况下交换值*
## Further Information 译注:“在某些情况下交换值”可以假设有个可变数组,现在要通过两个可变引用来交换其中两个元素的值。但 Rust 显然不允许有两个对数组的可变引用,这时候可以用 Option 包装下元素值,比如:
``` rust
fn main() {
let mut array = vec![Some(1), Some(2)];
let a = array.get_mut(0).unwrap().take().unwrap();
let b = array.get_mut(1).unwrap().replace(a);
*array.get_mut(0).unwrap() = b;
println!("{:?}", array);// [Some(2), Some(1)]
}
```
嘿嘿,有点强行了。
[示例参考](https://zulip-archive.rust-lang.org/stream/122651-general/topic/.60Option.60.20.22swapping.20things.20out.20of.20difficult.20situations.22.3F.html)
[关于 Option 的描述来自于](https://doc.rust-lang.org/std/option/)
## 更多信息
- [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions) - [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
- [Option Module Documentation](https://doc.rust-lang.org/std/option/) - [Option Module Documentation](https://doc.rust-lang.org/std/option/)

@ -1,9 +1,9 @@
// option1.rs // option1.rs
// Make me compile! Execute `rustlings hint option1` for hints // 让我通过编译!执行 `rustlings hint option1` 获取提示!
// I AM NOT DONE // I AM NOT DONE
// you can modify anything EXCEPT for this function's sig // 你可以自由修改代码,但这个函数签名除外。
fn print_number(maybe_number: Option<u16>) { fn print_number(maybe_number: Option<u16>) {
println!("printing: {}", maybe_number.unwrap()); println!("printing: {}", maybe_number.unwrap());
} }

@ -1,11 +1,11 @@
// option2.rs // option2.rs
// Make me compile! Execute `rustlings hint option2` for hints // 让我通过编译!执行 `rustlings hint option2` 获取提示!
// I AM NOT DONE // I AM NOT DONE
fn main() { fn main() {
let optional_word = Some(String::from("rustlings")); let optional_word = Some(String::from("rustlings"));
// TODO: Make this an if let statement whose value is "Some" type // TODO:改成适用于值为 "Some" 类型的 if let 语句,
word = optional_word { word = optional_word {
println!("The word is: {}", word); println!("The word is: {}", word);
} else { } else {
@ -17,8 +17,8 @@ fn main() {
optional_integers_vec.push(Some(x)); optional_integers_vec.push(Some(x));
} }
// TODO: make this a while let statement - remember that vector.pop also adds another layer of Option<T> // TODO:改成 while let 语句——记住vector.pop 的返回类型为 Option<T>。
// You can stack `Option<T>`'s into while let and if let // 你可以多次层叠地对 `Option<T>` 使用 while let 或 if let
integer = optional_integers_vec.pop() { integer = optional_integers_vec.pop() {
println!("current value: {}", integer); println!("current value: {}", integer);
} }

@ -1,5 +1,5 @@
// option3.rs // option3.rs
// Make me compile! Execute `rustlings hint option3` for hints // 让我通过编译!执行 `rustlings hint option3` 获取提示
// I AM NOT DONE // I AM NOT DONE
@ -15,5 +15,5 @@ fn main() {
Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y), Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y),
_ => println!("no match"), _ => println!("no match"),
} }
y; // Fix without deleting this line. y; // 无需删除这行就可以解决。
} }

@ -549,15 +549,15 @@ name = "option1"
path = "exercises/option/option1.rs" path = "exercises/option/option1.rs"
mode = "compile" mode = "compile"
hint = """ hint = """
Hint 1: Check out some functions of Option: 1 Option
is_some is_some
is_none is_none
unwrap unwrap
and:
pattern matching
Hint 2: There are no sensible defaults for the value of an Array; the values need to be filled before use. 2使
""" """
[[exercises]] [[exercises]]
@ -565,13 +565,13 @@ name = "option2"
path = "exercises/option/option2.rs" path = "exercises/option/option2.rs"
mode = "compile" mode = "compile"
hint = """ hint = """
check out:
https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html
https://doc.rust-lang.org/rust-by-example/flow_control/while_let.html https://doc.rust-lang.org/rust-by-example/flow_control/while_let.html
Remember that Options can be stacked in if let and while let. Options 使 if let while let
For example: Some(Some(variable)) = variable2 : Some(Some(variable)) = variable2
Also see Option::flatten Option::flatten
""" """
[[exercises]] [[exercises]]
@ -579,10 +579,9 @@ name = "option3"
path = "exercises/option/option3.rs" path = "exercises/option/option3.rs"
mode = "compile" mode = "compile"
hint = """ hint = """
The compiler says a partial move happened in the `match` `match`
statement. How can this be avoided? The compiler shows the correction
needed. After making the correction as suggested by the compiler, do https://doc.rust-lang.org/std/keyword.ref.html"""
read: https://doc.rust-lang.org/std/keyword.ref.html"""
# TRAITS # TRAITS

Loading…
Cancel
Save