Merge branch 'sunface:main' into main

pull/1126/head
Rustln 2 years ago committed by GitHub
commit 8e0f00bc06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -303,7 +303,7 @@ where
}
```
上面的缓存有一个很大的问题:只支持 `u32` 类型的值,若我们想要缓存 `String` 类型,显然就行不通了,因此需要将 `u32` 替换成泛型 `E`,该练习就留给读者自己完成,具体代码可以参考[这里](https://practice.rs/functional-programing/cloure.html#closure-in-structs)
上面的缓存有一个很大的问题:只支持 `u32` 类型的值,若我们想要缓存 `&str` 类型,显然就行不通了,因此需要将 `u32` 替换成泛型 `E`,该练习就留给读者自己完成,具体代码可以参考[这里](https://practice.rs/functional-programing/cloure.html#closure-in-structs)
## 捕获作用域中的值
@ -769,4 +769,4 @@ fn factory(x:i32) -> Box<dyn Fn(i32) -> i32> {
这块儿内容在进阶生命周期章节中有讲,这里就不再赘述,读者可移步[此处](https://course.rs/advance/lifetime/advance.html#闭包函数的消除规则)进行回顾。
{{#include ../../practice.md}}
{{#include ../../practice.md}}

@ -266,7 +266,7 @@ impl TimerFuture {
Rust 的 `Future` 是惰性的:只有屁股上拍一拍,它才会努力动一动。其中一个推动它的方式就是在 `async` 函数中使用 `.await` 来调用另一个 `async` 函数,但是这个只能解决 `async` 内部的问题,那么这些最外层的 `async` 函数,谁来推动它们运行呢?答案就是我们之前多次提到的执行器 `executor`
执行器会管理一批 `Future` (最外层的 `ascyn` 函数),然后通过不停地 `poll` 推动它们直到完成。 最开始,执行器会先 `poll` 一次 `Future` ,后面就不会主动去 `poll` 了,而是等待 `Future` 通过调用 `wake` 函数来通知它可以继续,它才会继续去 `poll` 。这种**wake 通知然后 poll**的方式会不断重复,直到 `Future` 完成。
执行器会管理一批 `Future` (最外层的 `async` 函数),然后通过不停地 `poll` 推动它们直到完成。 最开始,执行器会先 `poll` 一次 `Future` ,后面就不会主动去 `poll` 了,而是等待 `Future` 通过调用 `wake` 函数来通知它可以继续,它才会继续去 `poll` 。这种**wake 通知然后 poll**的方式会不断重复,直到 `Future` 完成。
#### 构建执行器

@ -287,15 +287,15 @@ struct Song {
async fn learn_song() -> Song {
Song {
author: "曲婉婷".to_string(),
name: String::from("《我的歌声里》"),
author: "周杰伦".to_string(),
name: String::from("《菊花台》"),
}
}
async fn sing_song(song: Song) {
println!(
"给大家献上一首{}的{} ~ {}",
song.author, song.name, "你存在我深深的脑海里~ ~"
song.author, song.name, "菊花残,满地伤~ ~"
);
}

@ -77,7 +77,7 @@ Rust 语言的安全可靠性顺理成章的影响了 `tokio` 的可靠性,曾
- **发送少量 HTTP 请求**。`tokio` 的优势是给予你并发处理大量任务的能力,对于这种轻量级 HTTP 请求场景,`tokio` 除了增加你的代码复杂性,并无法带来什么额外的优势。因此,对于这种场景,你可以使用 [`reqwest`](https://github.com/seanmonstar/reqwest) 库,它会更加简单易用。
> 若大家使用 tokio那 CPU 密集的任务尤其需要用线程的方式去处理,例如使用 `spawn_blocking` 创建一个阻塞的线程完成相应 CPU 密集任务。
> 若大家使用 tokio那 CPU 密集的任务尤其需要用线程的方式去处理,例如使用 `spawn_blocking` 创建一个阻塞的线程完成相应 CPU 密集任务。
>
> 原因是tokio 是协作式的调度器,如果某个 CPU 密集的异步任务是通过 tokio 创建的那理论上来说该异步任务需要跟其它的异步任务交错执行最终大家都得到了执行皆大欢喜。但实际情况是CPU 密集的任务很可能会一直霸着着 CPU此时 tokio 的调度方式决定了该任务会一直被执行,这意味着,其它的异步任务无法得到执行的机会,最终这些任务都会因为得不到资源而饿死。
>

@ -55,6 +55,16 @@ Rust 使用一个相对传统的语法来创建整数(`1``2`...)和浮
- 使用 `overflowing_*` 方法返回该值和一个指示是否存在溢出的布尔值
- 使用 `saturating_*` 方法使值达到最小值或最大值
下面是一个演示`wrapping_*`方法的示例:
```rust
fn main() {
let a : u8 = 255;
let b = a.wrapping_add(20);
println!("{}", b); // 19
}
```
## 浮点类型
**浮点类型数字** 是带有小数点的数字,在 Rust 中浮点类型数字也有两种基本类型: `f32``f64`,分别为 32 位和 64 位大小。默认浮点类型是 `f64`,在现代的 CPU 中它的速度与 `f32` 几乎相同,但精度更高。
@ -236,8 +246,8 @@ Rust的运算基本上和其他语言一样
| \| 位或 | 相同位置只要有1时则为1否则为0 |
| ^ 异或 | 相同位置不相同则为1相同则为0 |
| ! 位非 | 把位中的0和1相互取反即0置为11置为0 |
| << 左移 | 所有位向左移动指定位数,右位补 |
| >> 右移 | 所有位向右移动指定位数,左位补零 |
| << 左移 | 所有位向左移动指定位数,右位补0 |
| >> 右移 | 所有位向右移动指定位数,带符号移动正数补0负数补1 |
@ -342,4 +352,3 @@ use num::complex::Complex;

@ -1,6 +1,6 @@
# 复合类型
行百里者半十,欢迎大家来到这里,虽然还不到中点,但是已经不远了。如果说之前学的基础数据类型是原子,那么本章将讲的数据类型可以认为是分子。
行百里者半十,欢迎大家来到这里,虽然还不到中点,但是已经不远了。如果说之前学的基础数据类型是原子,那么本章将讲的数据类型可以认为是分子。
本章的重点在复合类型上,顾名思义,复合类型是由其它类型组合而成的,最典型的就是结构体 `struct` 和枚举 `enum`。例如平面上的一个点 `point(x, y)`,它由两个数值类型的值 `x``y` 组合而来。我们无法单独去维护这两个数值,因为单独一个 `x` 或者 `y` 是含义不完整的,无法标识平面上的一个点,应该把它们看作一个整体去理解和处理。

Loading…
Cancel
Save