错误处理
分类:
- 可恢复的错误
recoverable
,对应Result<T, E>
类型 - 不可恢复的错误
unrecoverable
,对应panic!
宏
panic! 与不可恢复的错误
Result 与可恢复的错误
匹配不同的错误
失败时 panic 的简写: unwrap 和 expect
unwrap:如果 Result 值是成员 Ok , unwrap 会返回 Ok 中的值。如果Result 是成员 Err , unwrap 会为我们调用 panic!
expect 与 unwrap 的使用方式一样:返回Ok或调用 panic! 宏。 expect 用来调用panic! 的错误信息将会作为参数传递给 expect
传播错误
谁来处理错误的问题:调用都来处理还是在调用中去处理
传播错误的简写: ?
运算符
- 如果Result的值是Ok,这个表达式将会返回Ok中的值而程序将继续执行。
- 如果值是 Err,Err中的值将作为整个函数的返回值,就好像使用了
return
关键字一样,这样错误值就被传播给了调用者。
一个函数中可能有多个不同的错误,如何转换?
问号运算符:?
运算符所使用的错误值被传递给了from函数,它定义于标准库的From
trait 中,其用来将错误从一种类型转换为另 一种类型。当 ? 运算符调用from函数时,收到的错误类型被转换为定义为当前函数返回的错误类型。
这在当一个函数返回一个错误类型来代表所有可能失败的方式时很有用,即使其可能会因很多种原因失败。只要每一个错误类型都实现了 from 函数来定义如将其转换为返回的错误类型, ? 运算符会自动处理这些转换
? 运算符可被用于返回 Result 的函数
main特殊性,有两种返回值类型:
- ()
- Result<T,E>
panic! 还是不 panic!
示例、代码原型和测试都非常适合 panic
当我们比编译器知道更多的情况
错误处理指导原则
- 有害状态并不包含 预期 会偶尔发生的错误
- 之后的代码的运行依赖于处于这种有害状态
- 当没有可行的手段来将有害状态信息编码进所使用的类型中的情况
创建自定义类型进行有效性验证 guessing_game2