From 698626c2be25b481d242f6895befc946602a5e8f Mon Sep 17 00:00:00 2001 From: sunface Date: Sat, 12 Feb 2022 16:43:09 +0800 Subject: [PATCH] upadte img sources --- book/contents/advance/circle-self-ref/circle-reference.md | 4 ++-- .../concurrency-with-threads/concurrency-parallelism.md | 2 +- book/contents/advance/concurrency-with-threads/thread.md | 2 +- book/contents/async/getting-started.md | 2 +- book/contents/async/pin-unpin.md | 4 ++-- book/contents/basic/base-type/function.md | 2 +- book/contents/basic/compound-type/string-slice.md | 2 +- book/contents/basic/compound-type/struct.md | 2 +- book/contents/basic/method.md | 2 +- book/contents/basic/ownership/borrowing.md | 2 +- book/contents/basic/ownership/ownership.md | 2 +- book/contents/basic/trait/trait-object.md | 2 +- book/contents/tokio/overview.md | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/book/contents/advance/circle-self-ref/circle-reference.md b/book/contents/advance/circle-self-ref/circle-reference.md index 41042f90..a6011dc0 100644 --- a/book/contents/advance/circle-self-ref/circle-reference.md +++ b/book/contents/advance/circle-self-ref/circle-reference.md @@ -28,7 +28,7 @@ fn main() {} 这里我们创建一个有些复杂的枚举类型 `List`,这个类型很有意思,它的每个值都指向了另一个 `List`,此外,得益于 `Rc` 的使用还允许多个值指向一个 `List`: - + 如上图所示,每个矩形框节点都是一个 `List` 类型,它们或者是拥有值且指向另一个 `List` 的`Cons`,或者是一个没有值的终结点 `Nil`。同时,由于 `RefCell` 的使用,每个 `List` 所指向的 `List` 还能够被修改。 @@ -81,7 +81,7 @@ b指向的节点 = Some(RefCell { value: Cons(5, RefCell { value: Nil }) }) 在 `main` 函数结束前,`a` 和 `b` 的引用计数均是 `2`,随后 `b` 触发 `Drop`,此时引用计数会变为 `1`,并不会归 `0`,因此 `b` 所指向内存不会被释放,同理可得 `a` 指向的内存也不会被释放,最终发生了内存泄漏。 下面一张图很好的展示了这种引用循环关系: - + 现在我们还需要轻轻的推一下,让塔米诺骨牌轰然倒塌。反注释最后一行代码,试着运行下: ```console diff --git a/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md b/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md index 4e323bc2..110b82b3 100644 --- a/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md +++ b/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md @@ -6,7 +6,7 @@ `Erlang` 之父[`Joe Armstrong`](https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer))(伟大的异步编程先驱,开创一个时代的殿堂级计算机科学家,我还犹记得当年刚学到 `Erlang` 时的震撼,respect!)用一张5岁小孩都能看到的图片解释了并发与并行的区别: - + 上图很直观的体现了: diff --git a/book/contents/advance/concurrency-with-threads/thread.md b/book/contents/advance/concurrency-with-threads/thread.md index 95805e26..37a350c0 100644 --- a/book/contents/advance/concurrency-with-threads/thread.md +++ b/book/contents/advance/concurrency-with-threads/thread.md @@ -246,7 +246,7 @@ for handle in handles { 下图是该代码在 `48` 核机器上的运行结果: - + 从图上可以明显的看出: 吞吐并不是线性增长,尤其从 `16` 核开始,甚至开始肉眼可见的下降,这是为什么呢? diff --git a/book/contents/async/getting-started.md b/book/contents/async/getting-started.md index 6def90fe..8dcc0317 100644 --- a/book/contents/async/getting-started.md +++ b/book/contents/async/getting-started.md @@ -3,7 +3,7 @@ 我们先通过一张web框架性能对比图来感受下 Rust 异步编程的性能: -actix-vs-gin screenshot +actix-vs-gin screenshot 上图并不能说 Rust 写的 `actix` 框架比 Go 的 `gin` 更好、更优秀,但是确实可以一定程度上说明 Rust 的异步性能非常的高! diff --git a/book/contents/async/pin-unpin.md b/book/contents/async/pin-unpin.md index 512be531..5c76b128 100644 --- a/book/contents/async/pin-unpin.md +++ b/book/contents/async/pin-unpin.md @@ -109,7 +109,7 @@ pub struct Pin

{ 它包裹一个指针,并且能确保该指针指向的数据不会被移动,例如 `Pin<&mut T>` , `Pin<&T>` , `Pin>` ,都能确保 `T` 不会被移动。 - + 而 `Unpin` 才是一个特征,它表明一个类型可以随意被移动,那么问题来了,可以被 `Pin` 住的值,它有没有实现什么特征呢? 答案很出乎意料,可以被 `Pin` 住的值实现的特征是 `!Unpin` ,大家可能之前没有见过,但是它其实很简单,`!` 代表没有实现某个特征的意思,`!Unpin` 说明类型没有实现 `Unpin` 特征,那自然就可以被 `Pin` 了。 @@ -228,7 +228,7 @@ fn main() { 下面的图片也可以帮助更好的理解这个过程: - + ## Pin 在实践中的运用 在理解了 `Pin` 的作用后,我们再来看看它怎么帮我们解决问题。 diff --git a/book/contents/basic/base-type/function.md b/book/contents/basic/base-type/function.md index 67d1db9d..d303f739 100644 --- a/book/contents/basic/base-type/function.md +++ b/book/contents/basic/base-type/function.md @@ -12,7 +12,7 @@ fn add(i: i32, j: i32) -> i32 { 该函数如此简单,但是又是如此的五脏俱全,声明函数的关键字 `fn` ,函数名 `add()`,参数 `i` 和 `j`,参数类型和返回值类型都是 `i32`,总之一切那么的普通,但是又那么的自信,直到你看到了下面这张图: - + 当你看懂了这张图,其实就等于差不多完成了函数章节的学习,但是这么短的章节显然对不起读者老爷们的厚爱,所以我们来展开下。 diff --git a/book/contents/basic/compound-type/string-slice.md b/book/contents/basic/compound-type/string-slice.md index 49c935d2..e8df1310 100644 --- a/book/contents/basic/compound-type/string-slice.md +++ b/book/contents/basic/compound-type/string-slice.md @@ -51,7 +51,7 @@ let world = &s[6..11]; 对于 `let world = &s[6..11];` 来说,`world` 是一个切片,该切片的指针指向 `s` 的第 7 个字节(索引从 0 开始, 6 是第 7 个字节),且该切片的长度是 `5` 个字节。 - + 在使用 Rust 的 `..` [range序列](../base-type/numbers.md#序列(Range))语法时,如果你想从索引 0 开始,可以使用如下的方式,这两个是等效的: ```rust diff --git a/book/contents/basic/compound-type/struct.md b/book/contents/basic/compound-type/struct.md index d501ffed..6d3e7922 100644 --- a/book/contents/basic/compound-type/struct.md +++ b/book/contents/basic/compound-type/struct.md @@ -162,7 +162,7 @@ println!("{:?}", user1); ``` 上面定义的 `File` 结构体在内存中的排列如下图所示: - + 从图中可以清晰的看出 `File` 结构体两个字段 `name` 和 `data` 分别拥有底层两个 `[u8]` 数组的所有权(`String` 类型的底层也是 `[u8]` 数组),通过 `ptr` 指针指向底层数组的内存地址,这里你可以把 `ptr` 指针理解为 Rust 中的引用类型。 diff --git a/book/contents/basic/method.md b/book/contents/basic/method.md index df385cdc..030cd3bd 100644 --- a/book/contents/basic/method.md +++ b/book/contents/basic/method.md @@ -36,7 +36,7 @@ impl Circle { 我们这里先不详细展开讲解,只是先建立对方法定义的大致印象。下面的图片将 Rust 方法定义与其它语言的方法定义做了对比: - + 可以看出,其它语言中所有定义都在 `class` 中,但是 Rust 的对象定义和方法定义是分离的,这种数据和使用分离的方式,会给予使用者极高的灵活度。 diff --git a/book/contents/basic/ownership/borrowing.md b/book/contents/basic/ownership/borrowing.md index 429632f3..86033552 100644 --- a/book/contents/basic/ownership/borrowing.md +++ b/book/contents/basic/ownership/borrowing.md @@ -58,7 +58,7 @@ fn calculate_length(s: &String) -> usize { 2. `calculate_length` 的参数 `s` 类型从 `String` 变为 `&String` 这里,`&` 符号即是引用,它们允许你使用值,但是不获取所有权,如图所示: -&String s pointing at String s1 +&String s pointing at String s1 通过 `&s1` 语法,我们创建了一个 **指向s1的引用**,但是并不拥有它。因为并不拥有这个值,当引用离开作用域后,其指向的值也不会被丢弃。 diff --git a/book/contents/basic/ownership/ownership.md b/book/contents/basic/ownership/ownership.md index f3950052..0131ea9f 100644 --- a/book/contents/basic/ownership/ownership.md +++ b/book/contents/basic/ownership/ownership.md @@ -190,7 +190,7 @@ error[E0382]: use of moved value: `s1` 如果你在其他语言中听说过术语**浅拷贝( shallow copy )**和**深拷贝( deep copy )**,那么拷贝指针、长度和容量而不拷贝数据听起来就像浅拷贝,但是又因为 Rust 同时使第一个变量 `s1` 无效了,因此这个操作被称为**移动(move)**,而不是浅拷贝。上面的例子可以解读为 `s1` 被**移动**到了 `s2` 中。那么具体发生了什么,用一张图简单说明: -s1 moved to s2 +s1 moved to s2 这样就解决了我们之前的问题,`s1` 不再指向任何数据,只有 `s2` 是有效的,当 `s2` 离开作用域,它就会释放内存。 相信此刻,你应该明白了,为什么 Rust 称呼 `let a = b` 为**变量绑定**了吧? diff --git a/book/contents/basic/trait/trait-object.md b/book/contents/basic/trait/trait-object.md index 8ecfe6c7..d4d72d97 100644 --- a/book/contents/basic/trait/trait-object.md +++ b/book/contents/basic/trait/trait-object.md @@ -263,7 +263,7 @@ help: function arguments must have a statically known size, borrowed types alway 下面这张图很好的解释了静态分发 `Box` 和动态分发 `Box` 的区别: - + ## Self与self 在 Rust 中,有两个`self`,一个指代当前的实例对象,一个指代特征或者方法类型的别名: diff --git a/book/contents/tokio/overview.md b/book/contents/tokio/overview.md index cafba591..ef9d62bc 100644 --- a/book/contents/tokio/overview.md +++ b/book/contents/tokio/overview.md @@ -44,7 +44,7 @@ tokio是一个纸醉金迷之地,只要有钱就可以为所欲为,哦,抱 因为快所以快,前者是 Rust 快,后者是 `tokio` 快。 `tokio` 在编写时充分利用了 Rust 提供的各种零成本抽象和高性能特性,而且贯彻了 Rust 的牛逼思想:如果你选择手写代码,那么最好的结果就是跟 `tokio` 一样快! 以下是一张官方提供的性能参考图,大致能体现出 `tokio` 的性能之恐怖: -tokio performance +tokio performance **高可靠**