From a46feabb5a37a34379ab81ccdb382ff10a62e323 Mon Sep 17 00:00:00 2001 From: zongzi531 Date: Thu, 3 Mar 2022 13:03:01 +0800 Subject: [PATCH 1/7] Fix typo in smart-pointer/box.md --- src/advance/smart-pointer/box.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advance/smart-pointer/box.md b/src/advance/smart-pointer/box.md index 1f863754..72797f60 100644 --- a/src/advance/smart-pointer/box.md +++ b/src/advance/smart-pointer/box.md @@ -8,7 +8,7 @@ 栈内存从高位地址向下增长,且栈内存是连续分配的,一般来说**操作系统对栈内存的大小都有限制**,因此 C 语言中无法创建任意长度的数组。在 Rust 中,`main` 线程的[栈大小是 `8MB`](https://course.rs/pitfalls/stack-overflow.html),普通线程是 `2MB`,在函数调用时会在其中创建一个临时栈空间,调用结束后 Rust 会让这个栈空间里的对象自动进入 `Drop` 流程,最后栈顶指针自动移动到上一个调用栈顶,无需程序员手动干预,因而栈内存申请和释放是非常高效的。 -与栈相反,堆上内存则是从低位地址向上增长,**堆内存通常只受物理内存限制**,而且通常是不连续的,因此从性能的角度看,栈往往比对堆更高。 +与栈相反,堆上内存则是从低位地址向上增长,**堆内存通常只受物理内存限制**,而且通常是不连续的,因此从性能的角度看,栈往往比堆更高。 相比其它语言,Rust 堆上对象还有一个特殊之处,它们都拥有一个所有者,因此受所有权规则的限制:当赋值时,发生的是所有权的转移(只需浅拷贝栈上的引用或智能指针即可),例如以下代码: ```rust From ddbe1105d2702f4208cacb2148c06b44a44277ab Mon Sep 17 00:00:00 2001 From: zongzi531 Date: Thu, 3 Mar 2022 13:35:35 +0800 Subject: [PATCH 2/7] Fix typo in smart-pointer/box.md --- src/advance/smart-pointer/box.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/advance/smart-pointer/box.md b/src/advance/smart-pointer/box.md index 1f863754..71925bc5 100644 --- a/src/advance/smart-pointer/box.md +++ b/src/advance/smart-pointer/box.md @@ -183,6 +183,7 @@ fn main() { 那如果数组中每个元素都是一个 `Box` 对象呢?来看看 `Vec>` 的内存布局: ```rust + (heap) (stack) (heap) ┌───┐ ┌──────┐ ┌───┐ ┌─→│ 1 │ │ vec2 │──→│B1 │─┘ └───┘ @@ -234,7 +235,7 @@ fn gen_static_str() -> &'static str{ } ``` -在之前的代码中,如果 `String` 创建于函数中,那么返回它的唯一方法就是转移所有权给调用者 `fn move_str() -> String`,而通过 `Box::leak` 我们不仅返回了一个 `&str` 字符串切片,它还是 `'static` 类型的! +在之前的代码中,如果 `String` 创建于函数中,那么返回它的唯一方法就是转移所有权给调用者 `fn move_str() -> String`,而通过 `Box::leak` 我们不仅返回了一个 `&str` 字符串切片,它还是 `'static` 生命周期的! 要知道真正具有 `'static` 生命周期的往往都是编译期就创建的值,例如 `let v = "hello, world"`,这里 `v` 是直接打包到二进制可执行文件中的,因此该字符串具有 `'static` 生命周期,再比如 `const` 常量。 From 6757bb9114581474d74c40dc0f856399aae8d8c7 Mon Sep 17 00:00:00 2001 From: BobH Date: Thu, 3 Mar 2022 16:14:18 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E4=B8=80=E6=AE=B5=E9=87=8D=E5=A4=8D=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=EF=BC=88=E8=8B=B1=E6=96=87=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/basic/compound-type/string-slice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/basic/compound-type/string-slice.md b/src/basic/compound-type/string-slice.md index a0a36e43..e59d4f3c 100644 --- a/src/basic/compound-type/string-slice.md +++ b/src/basic/compound-type/string-slice.md @@ -195,7 +195,7 @@ fn main() { let s1 = String::from("hello,"); let s2 = String::from("world!"); // 在下句中,s1的所有权被转移走了,因此后面不能再使用s1 - let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used + let s3 = s1 + &s2; assert_eq!(s3,"hello,world!"); // 下面的语句如果去掉注释,就会报错 // println!("{}",s1); From 0f021668b99c09ba8b5a0e126bddf91b7af3f2bd Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 4 Mar 2022 08:55:01 +0800 Subject: [PATCH 4/7] fix outdated links --- src/first-try/cargo.md | 8 ++++---- src/profiling/compiler/speed-up.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/first-try/cargo.md b/src/first-try/cargo.md index cc5bc5c4..e99155f0 100644 --- a/src/first-try/cargo.md +++ b/src/first-try/cargo.md @@ -114,7 +114,7 @@ $ cargo check Finished dev [unoptimized + debuginfo] target(s) in 0.06s ``` -> Rust 虽然编译速度还行,但是还是不能 Go 语言相提并论,因为 Rust 需要做很多复杂的编译优化和语言特性解析,甚至连如何优化编译速度都成了一门学问 [优化编译速度](../profiling/compiler/speed-up.md) +> Rust 虽然编译速度还行,但是还是不能 Go 语言相提并论,因为 Rust 需要做很多复杂的编译优化和语言特性解析,甚至连如何优化编译速度都成了一门学问: [优化编译速度](../profiling/compiler/speed-up.md) ## Cargo.toml 和 Cargo.lock @@ -139,7 +139,7 @@ version = "0.1.0" edition = "2021" ``` -`name` 字段定义了项目名称,`version` 字段定义当前版本,新项目默认是 `0.1.0`,`edition` 字段定义了我们使用的 Rust 大版本。因为本书很新(不仅仅是现在新,未来也将及时修订,跟得上 Rust 的小步伐),所以使用的是 `Rust edition 2021` 大版本,详情见 [Rust 版本详解](../appendix/rust-version.md) +`name` 字段定义了项目名称,`version` 字段定义当前版本,新项目默认是 `0.1.0`,`edition` 字段定义了我们使用的 Rust 大版本。因为本书很新(不仅仅是现在新,未来也将及时修订,跟得上 Rust 的小步伐),所以使用的是 `Rust edition 2021` 大版本,详情见 [Rust 版本详解](https://course.rs/appendix/rust-version.html) ### 定义项目依赖 @@ -161,10 +161,10 @@ color = { git = "https://github.com/bjz/color-rs" } geometry = { path = "crates/geometry" } ``` -相信聪明的读者已经能看懂该如何引入外部依赖库,这里就不再赘述。详细的说明参见此章:[Cargo 依赖管理](../cargo/dependency.md),但是不建议大家现在去看,只要按照目录浏览,拨云见雾指日可待。 +相信聪明的读者已经能看懂该如何引入外部依赖库,这里就不再赘述。详细的说明参见此章:[Cargo 依赖管理](https://course.rs/cargo/reference/specify-deps.html),但是不建议大家现在去看,只要按照目录浏览,拨云见雾指日可待。 ## 基于 cargo 的项目组织结构 -前文有提到 `cargo` 默认生成的项目结构,真实的项目肯定会有所不同,但是在目前的学习阶段,还无需关注。感兴趣的同学可以移步:[Cargo 项目结构](../cargo/guide/package-layout.md) +前文有提到 `cargo` 默认生成的项目结构,真实的项目肯定会有所不同,但是在目前的学习阶段,还无需关注。感兴趣的同学可以移步:[Cargo 项目结构](https://course.rs/cargo/guide/package-layout.html ) 至此,大家对 Rust 项目的创建和管理已经有了初步的了解,那么来完善刚才的`"世界,你好"`项目吧。 diff --git a/src/profiling/compiler/speed-up.md b/src/profiling/compiler/speed-up.md index 2416d9e3..d7b9feb5 100644 --- a/src/profiling/compiler/speed-up.md +++ b/src/profiling/compiler/speed-up.md @@ -1,9 +1,9 @@ # 优化编译速度 - + \ No newline at end of file From 332969362ec1d7af3ae23d24c334e9655b0592e9 Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 4 Mar 2022 10:22:17 +0800 Subject: [PATCH 5/7] add linked-list/intro.md --- src/SUMMARY.md | 2 ++ src/linked-list/intro.md | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/linked-list/intro.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 8d182978..25bb5ff9 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -153,6 +153,8 @@ - [构建脚本 build.rs](cargo/reference/build-script/intro.md) - [构建脚本示例](cargo/reference/build-script/examples.md) +- [手把手带你实现链表 doing](linked-list/intro.md) + - [易混淆概念解析](confonding/intro.md) - [切片和切片引用](confonding/slice.md) - [String、&str 和 str](confonding/string.md) diff --git a/src/linked-list/intro.md b/src/linked-list/intro.md new file mode 100644 index 00000000..a3b0e8e5 --- /dev/null +++ b/src/linked-list/intro.md @@ -0,0 +1,13 @@ +# 手把手带你实现链表 + +> 其它语言:兄弟,语言学了吗?来写一个链表证明你基本掌握了语法。 +> +> Rust 语言: 兄弟,语言精通了吗?来写一个链表证明你已经精通了 Rust! + + +上面的对话非常真实,我们在之前的章节也讲过[初学者学习 Rust 应该避免的坑](https://course.rs/sth-you-should-not-do.html#千万别从链表或图开始练手),其中最重要的就是 - 不要写链表或者类似的数据结构! + +而本章,你就将见识到何为真正的深坑,看完后,就知道没有提早跳进去是一个多么幸运的事。总之,在专题中,你将学会如何使用 Rust 来实现链表。 + + +**专题内容翻译自英文开源书 [Learning Rust With Entirely Too Many Linked Lists](https://rust-unofficial.github.io/too-many-lists/),但是在内容上做了一些调整,希望大家喜欢。** \ No newline at end of file From 539a700930e29c6def24b72a9cd65c744ddf0277 Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 4 Mar 2022 10:23:24 +0800 Subject: [PATCH 6/7] update changelog --- 内容变更记录.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/内容变更记录.md b/内容变更记录.md index 8c1597f1..24fdad95 100644 --- a/内容变更记录.md +++ b/内容变更记录.md @@ -1,6 +1,11 @@ # ChangeLog 记录一些值得注意的变更。 +## 2022-03-04 + +- 新增专题: [手把手带你实现链表](https://course.rs/linked-list/intro) + + ## 2022-03-03 - 新增章节: [Cargo - 构建脚本示例](https://course.rs/cargo/reference/build-script/examples.html) From a28859338ced3b6b137c26a61cddc0f9771f38bd Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 4 Mar 2022 12:11:18 +0800 Subject: [PATCH 7/7] fix invalid link --- src/test/write-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/write-tests.md b/src/test/write-tests.md index 58f24a26..7c999e78 100644 --- a/src/test/write-tests.md +++ b/src/test/write-tests.md @@ -66,7 +66,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; fini 关于 `filtered` 和 `ignored` 的使用,在本章节的后续内容我们会讲到,这里暂且略过。 -还有一个很重要的点,输出中的 `Doc-tests adder` 代表了文档测试,由于我们的代码中没有任何文档测试的内容,因此这里的测试用例数为 `0`,关于文档测试的详细介绍请参见[这里](https://course.rs/advance/comment.html#文档测试doc-test)。 +还有一个很重要的点,输出中的 `Doc-tests adder` 代表了文档测试,由于我们的代码中没有任何文档测试的内容,因此这里的测试用例数为 `0`,关于文档测试的详细介绍请参见[这里](https://course.rs/basic/comment.html#文档注释)。 大家还可以尝试修改下测试函数的名称,例如修改为 `exploration`,看看运行结果将如何变化。