Merge pull request #325 from glud123/main

fix:修复语句不通、打字错误的问题
pull/329/head
Sunface 3 years ago committed by GitHub
commit a1de7f9eb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -163,7 +163,7 @@ error[E0277]: the trait bound `&mut i32: Trait` is not satisfied
再进一步,我们使用[完全限定语法](https://course.rs/basic/trait/advance-trait.html#完全限定语法)来进行准确的函数调用:
1. 首先,编译器检查它是否可以直接调用 `T::foo(value)`,称之为**值方法调用**
2. 如果上一步调用无法完成(例如方法类型错误或者特征没有针对 `Self` 进行实现,上文提到过特征不能进行强制转换),那么编译器会尝试增加自动引用,以为着编译器会尝试以下调用: `<&T>::foo(value)``<&mut T>::foo(value)`,称之为**引用方法调用**
2. 如果上一步调用无法完成(例如方法类型错误或者特征没有针对 `Self` 进行实现,上文提到过特征不能进行强制转换),那么编译器会尝试增加自动引用,例如会尝试以下调用: `<&T>::foo(value)``<&mut T>::foo(value)`,称之为**引用方法调用**
3. 若上面两个方法依然不工作,编译器会试着解引用 `T` ,然后再进行尝试。这里使用了 `Deref` 特征 —— 若 `T: Deref<Target = U>` (`T` 可以被解引用为 `U`),那么编译器会使用 `U` 类型进行尝试,称之为**解引用方法调用**
4. 若 `T` 不能被解引用,且 `T` 是一个定长类型(在编译器类型长度是已知的),那么编译器也会尝试将 `T` 从定长类型转为不定长类型,例如将 `[i32; 2]` 转为 `[i32]`
5. 若还是不行,那...没有那了,最后编译器大喊一声:汝欺我甚,不干了!
@ -189,7 +189,7 @@ fn do_stuff<T: Clone>(value: &T) {
let cloned = value.clone();
}
```
上面例子中 `cloned` 的类型什么?首先编译器检查能不能进行**值方法调用** `value` 的类型是 `&T`,同时 `clone` 方法的签名也是 `&T` `fn clone(&T) -> T`,因此可以进行值方法调用,再加上编译器知道了 `T` 实现了 `Clone`,因此 `cloned` 的类型是 `T`
上面例子中 `cloned` 的类型什么?首先编译器检查能不能进行**值方法调用** `value` 的类型是 `&T`,同时 `clone` 方法的签名也是 `&T` `fn clone(&T) -> T`,因此可以进行值方法调用,再加上编译器知道了 `T` 实现了 `Clone`,因此 `cloned` 的类型是 `T`
如果 `T: Clone` 的特征约束被移除呢?
```rust

@ -88,7 +88,7 @@ note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose bac
panic = 'abort'
```
## 线程`panic`后,程序会终止?
## 线程`panic`后,程序是否会终止?
长话短说,如果是 `main` 线程,则程序会终止,如果是其它子线程,该线程会终止,但是不会影响 `main` 线程。因此,尽量不要在 `main` 线程中做太多任务,将这些任务交由子线程去做,就算子线程 `panic` 也不会导致整个程序的结束。
具体解析见[panic原理剖析](#panic原理剖析)
@ -136,7 +136,7 @@ let home: IpAddr = "127.0.0.1".parse().unwrap();
- 后续代码的运行会受到显著影响
- 内存安全的问题
当错误预期会出现时返回一个错误较为合适例如解析器接收到格式错误的数据HTTP请求接收到错误的参数甚至该请求内的任何错误(不会导致整个程序有问题,只影响该请求)。 **因为错误是可预期的,因此也是可以处理的**。
当错误预期会出现时返回一个错误较为合适例如解析器接收到格式错误的数据HTTP请求接收到错误的参数甚至该请求内的任何错误(不会导致整个程序有问题,只影响该请求)。 **因为错误是可预期的,因此也是可以处理的**。
当启动时某个流程发生了错误,对后续代码的运行造成了影响,那么就应该使用 `panic`,而不是处理错误后继续运行,当然你可以通过重试的方式来继续。
@ -155,5 +155,5 @@ let home: IpAddr = "127.0.0.1".parse().unwrap();
还有一种情况,在展开过程中,如果展开本身 `panic` 了,那展开线程会终止,展开也随之停止。
一旦线程展开被终止或者完成,最终的输出结果是取决于哪个线程 `panic:对于 `main` 线程,操作系统提供的终止功能 `core::intrinsics::abort()` 会被调用,最终结束当前的 `panic` 进程;如果是其它子线程,那么子线程就会简单的终止,同时信息会在稍后通过 `std::thread::join()` 进行收集。
一旦线程展开被终止或者完成,最终的输出结果是取决于哪个线程 `panic`:对于 `main` 线程,操作系统提供的终止功能 `core::intrinsics::abort()` 会被调用,最终结束当前的 `panic` 进程;如果是其它子线程,那么子线程就会简单的终止,同时信息会在稍后通过 `std::thread::join()` 进行收集。

Loading…
Cancel
Save