From 7d9e2e042f62ce2914ff5188d233a8de232ad5cc Mon Sep 17 00:00:00 2001 From: sunface Date: Wed, 15 Dec 2021 14:30:37 +0800 Subject: [PATCH] update --- README.md | 4 +--- book.toml | 4 ++-- release | 2 +- src/SUMMARY.md | 4 ++-- src/about-book.md | 4 +--- src/basic/intro.md | 2 +- src/basic/result-error/panic.md | 23 ++++++++++++------- src/fight-with-compiler/lifetime/too-long1.md | 2 ++ 8 files changed, 25 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 38f26949..bb20904f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ - 修订时间: **尚未发行** - Rust版本: Rust edition 2021 - QQ交流群: 1009730433 -- 主要作者:   [Sunface](https://im.dev) ### 教程简介 `Rust语言圣经`涵盖从**入门到精通**所需的全部Rust知识,目录及内容都经过深思熟虑的设计,同时语言生动幽默,行文流畅自如,摆脱技术书籍常有的机器味和晦涩感。 @@ -31,6 +30,5 @@ Rust语言圣经是**完全开源**的电子书, 每个章节都至少用时4-6 2. 英文资料难学(阅读较难的技术内容,需要精准阅读,因此对外语能力要求较高),中文资料也不太好学(内容全面度、实时性,晦涩难懂等) 3. 没有体系化的学习路线,新人往往扫完一遍入门书籍,就不知道何去何从 -为此,有了一本书和一个社区,欢迎大家的加入: -- https://college.rs +为此,我整了一本书和一个社区,欢迎大家的加入: - QQ群:1009730433 diff --git a/book.toml b/book.toml index d21b82f9..0555e919 100644 --- a/book.toml +++ b/book.toml @@ -6,8 +6,8 @@ title = "Rust语言圣经(Rust Course)" [output.html] additional-css = ["assets/ferris.css", "assets/theme/2018-edition.css"] additional-js = ["assets/ferris.js"] -git-repository-url = "https://github.com/rustcollege" -edit-url-template = "https://github.com/rustcollege/rust-course/edit/main/{path}" +git-repository-url = "https://github.com/sunface/rust-course" +edit-url-template = "https://github.com/sunface/rust-course/edit/main/{path}" [output.html.playground] editable = true diff --git a/release b/release index d8c70a5d..f77579bb 100755 --- a/release +++ b/release @@ -14,7 +14,7 @@ git config user.email "cto@188.com" git add . git commit -m 'release book' git branch -M gh-pages -git remote add origin https://github.com/rustcollege/rust-course +git remote add origin https://github.com/sunface/rust-course ## push to github pages git push -u -f origin gh-pages \ No newline at end of file diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ed05429d..16fa7b0e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -43,8 +43,8 @@ - [进一步深入特征](basic/trait/advance-trait.md) - [类型转换](basic/converse.md) - [返回和错误处理](basic/result-error/intro.md) - - [不可恢复错误panic!](basic/result-error/panic.md) - - [可恢复的错误Result](basic/result-error/result.md) + - [panic深入剖析!](basic/result-error/panic.md) + - [返回值Result和?](basic/result-error/result.md) - [Rust高级进阶 doing](advance/intro.md) diff --git a/src/about-book.md b/src/about-book.md index 8184c9f0..bb20904f 100644 --- a/src/about-book.md +++ b/src/about-book.md @@ -4,7 +4,6 @@ - 修订时间: **尚未发行** - Rust版本: Rust edition 2021 - QQ交流群: 1009730433 -- 主要作者: [Sunface](https://im.dev) ### 教程简介 `Rust语言圣经`涵盖从**入门到精通**所需的全部Rust知识,目录及内容都经过深思熟虑的设计,同时语言生动幽默,行文流畅自如,摆脱技术书籍常有的机器味和晦涩感。 @@ -31,6 +30,5 @@ Rust语言圣经是**完全开源**的电子书, 每个章节都至少用时4-6 2. 英文资料难学(阅读较难的技术内容,需要精准阅读,因此对外语能力要求较高),中文资料也不太好学(内容全面度、实时性,晦涩难懂等) 3. 没有体系化的学习路线,新人往往扫完一遍入门书籍,就不知道何去何从 -为此,有了一本书和一个社区,欢迎大家的加入: -- https://college.rs +为此,我整了一本书和一个社区,欢迎大家的加入: - QQ群:1009730433 diff --git a/src/basic/intro.md b/src/basic/intro.md index b36e2fb9..f382f360 100644 --- a/src/basic/intro.md +++ b/src/basic/intro.md @@ -5,7 +5,7 @@ - 宏编程 - 模式匹配 -类似的还有很多,不过不用怕,一方面,这本书会带你彻底探索这个神秘的大陆,另一方面,我们也有一个非常友善的社区,在里面你可以提问也可以分享自己的所学所思: [社区网址](https://community.college.rs). +类似的还有很多,不过不用怕,一方面,这本书会带你彻底探索这个神秘的大陆. 本章主要介绍Rust的基础语法、数据类型、项目结构等,学完本章,你将对Rust代码有一个清晰、完整的认识。 diff --git a/src/basic/result-error/panic.md b/src/basic/result-error/panic.md index 6b8f534a..4b6acca6 100644 --- a/src/basic/result-error/panic.md +++ b/src/basic/result-error/panic.md @@ -1,4 +1,4 @@ -# 不可恢复错误panic! +# panic深入剖析 在正式开始之前,先来思考一个问题: 假设我们想要从文件读取数据,如果失败,你有没有好的办法通知调用者为何失败?如果成功,你有没有好的办法把读取的结果返还给调用者? @@ -88,6 +88,11 @@ note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose bac panic = 'abort' ``` +## 线程`panic`后,程序会否终止? +长话短说,如果是`main`线程,则程序会终止,如果是其它子线程,该线程会终止。因此,尽量不要在`main`线程中做太多任务,将这些任务交由子线程去做,就算`panic`也不会导致整个程序的结束。 + +具体解析见[panic原理剖析](#panic原理剖析) + ## 何时该使用panic! 下面让我们大概罗列下合适适合使用`panic`,虽然原则上,你理解了之前的内容后,会自己作出合适的选择,但是罗列出来可以帮助你强化这一点。 @@ -140,13 +145,15 @@ let home: IpAddr = "127.0.0.1".parse().unwrap(); ## panic原理剖析 -本来不想写这块儿内容,因为对于大多数人都没有帮助,但是转念一想,既然号称圣经,那么本书就得与众不同,避重就轻显然不是该有的态度。 +本来不想写这块儿内容,因为真的难写,但是转念一想,既然号称圣经,那么本书就得与众不同,避重就轻显然不是该有的态度。 + +当调用`panic!`宏时,它会 +1. 格式化`panic`信息,然后使用该信息作为参数,调用`std::panic::panic_any()`函数 +2. `panic_any`会检查应用是否使用了`panic hook`,如果使用了,该`hook`函数会被调用 +3. 当`hook`函数返回后,当前的线程就开始进行栈展开:从`panic_any`开始,如果寄存器或者栈因为某些原因信息错乱了,那很可能该展开会发生异常,最终线程会直接停止,展开也无法继续进行。 +4. 展开的过程是一帧一帧的去回溯整个栈,每个帧的数据都会随之被丢弃,但是在展开过程中,你可能会遇到被用户标记为`catching`的帧(通过`std::panic::catch_unwind()`函数标记),此时用户提供的`catch`函数会被调用,展开也随之停止: 当然,如果`catch`选择在内部调用`std::panic::resume_unwind()`函数,则展开还会继续。 +还有一种情况,在展开过程中,如果展开本身`panic`了,那展开线程会终止,展开也随之停止。 +一旦线程展开被终止或者完成,最终的输出结果是取决于哪个线程`panic`:对于`main`线程,操作系统提供的终止功能`core::intrinsics::abort()`会被调用,最终结束当前的`panic`进程;如果是其它子线程,那么线程就会简单的终止,同时信息会在稍后通过`std::thread::join()`进行收集. -Not sure exactly what you're asking, but I'll try to describe the panic mechanism as I understand it. I'm sure folks will correct my mistakes. -When you call the panic!() macro it formats the panic message and then calls std::panic::panic_any() with the message as the argument. panic_any() first checks to see if there's a "panic hook" installed by the application: if so, the hook function is called. Assuming that the hook function returns, the unwinding of the current thread begins with the parent stack frame of the caller of panic_any(). If the registers or the stack are messed up, likely trying to start unwinding will cause an exception of some kind, at which point the thread will be aborted instead of unwinding. -Unwinding is a process of walking back up the stack, frame-by-frame. At each frame, any data owned by the frame is dropped. (I believe things are dropped in reverse static order, as they would be at the end of a function.) -One exceptional case during unwinding is that the unwinding may hit a frame marked as "catching" the unwind via std::panic::catch_unwind(). If so, the supplied catch function is called and unwinding ceases: the catching frame may continue the unwinding with std::panic::resume_unwind() or not. -Another exceptional case during unwinding is that some drop may itself panic. In this case the unwinding thread is aborted. -Once unwinding of a thread is aborted or completed (no more frames to unwind), the outcome depends on which thread panicked. For the main thread, the operating environment's abort functionality is invoked to terminate the panicking process via core::intrinsics::abort(). Child threads, on the other hand, are simply terminated and can be collected later with std::thread::join() \ No newline at end of file diff --git a/src/fight-with-compiler/lifetime/too-long1.md b/src/fight-with-compiler/lifetime/too-long1.md index 36deaf74..e30f2a5b 100644 --- a/src/fight-with-compiler/lifetime/too-long1.md +++ b/src/fight-with-compiler/lifetime/too-long1.md @@ -1,5 +1,7 @@ # 生命周期声明的范围过大 +在大多时候,Rust的生命周期你只要标识了,即可以通过编译,但是总是存在一些情况,会导致编译无法通过,本文就讲述这样一种情况:因为生命周期声明的范围过大,导致了编译无法通过,希望大家喜欢 + ## 例子1 ```rust struct Interface<'a> {