Merge pull request #703 from al00000/patch-3

Update ch12-03-improving-error-handling-and-modularity.md
pull/705/head
KaiserY 2 years ago committed by GitHub
commit 18d73f69f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -128,7 +128,7 @@
#### 从 `new` 中返回 `Result` 而不是调用 `panic!`
我们可以选择返回一个 `Result` 值,它在成功时会包含一个 `Config` 的实例,而在错误时会描述问题。当 `Config::new``main` 交流时,可以使用 `Result` 类型来表明这里存在问题。接着修改 `main``Err` 成员转换为对用户更友好的错误,而不是 `panic!` 调用产生的关于 `thread 'main'``RUST_BACKTRACE` 的文本。
我们可以选择返回一个 `Result` 值,它在成功时会包含一个 `Config` 的实例,而在错误时会描述问题。我们还将把函数名从`new`改为`build`,因为许多程序员希望 `new` 函数永远不会失败。`Config::new``main` 交流时,可以使用 `Result` 类型来表明这里存在问题。接着修改 `main``Err` 成员转换为对用户更友好的错误,而不是 `panic!` 调用产生的关于 `thread 'main'``RUST_BACKTRACE` 的文本。
示例 12-9 展示了为了返回 `Result``Config::new` 的返回值和函数体中所需的改变。注意这还不能编译,直到下一个示例同时也更新了 `main` 之后。
@ -138,17 +138,17 @@
{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-09/src/main.rs:here}}
```
<span class="caption">示例 12-9`Config::new` 中返回 `Result`</span>
<span class="caption">示例 12-9`Config::build` 中返回 `Result`</span>
现在 `new` 函数返回一个 `Result`,在成功时带有一个 `Config` 实例而在出现错误时带有一个 `&'static str`。回忆一下第十章 “静态生命周期” 中讲到 `&'static str` 是字符串字面值的类型,也是目前的错误信息。
现在 `build` 函数返回一个 `Result`,在成功时带有一个 `Config` 实例而在出现错误时带有一个 `&'static str`。回忆一下第十章 “静态生命周期” 中讲到 `&'static str` 是字符串字面值的类型,也是目前的错误信息。
`new` 函数体中有两处修改:当没有足够参数时不再调用 `panic!`,而是返回 `Err` 值。同时我们将 `Config` 返回值包装进 `Ok` 成员中。这些修改使得函数符合其新的类型签名。
通过让 `Config::new` 返回一个 `Err` 值,这就允许 `main` 函数处理 `new` 函数返回的 `Result` 值并在出现错误的情况更明确的结束进程。
通过让 `Config::build` 返回一个 `Err` 值,这就允许 `main` 函数处理 `new` 函数返回的 `Result` 值并在出现错误的情况更明确的结束进程。
#### `Config::new` 调用并处理错误
#### `Config::build` 调用并处理错误
为了处理错误情况并打印一个对用户友好的信息,我们需要像示例 12-10 那样更新 `main` 函数来处理现在 `Config::new` 返回的 `Result`。另外还需要手动实现原先由 `panic!`负责的工作,即以非零错误码退出命令行工具的工作。非零的退出状态是一个惯例信号,用来告诉调用程序的进程:该程序以错误状态退出了。
为了处理错误情况并打印一个对用户友好的信息,我们需要像示例 12-10 那样更新 `main` 函数来处理现在 `Config::build` 返回的 `Result`。另外还需要手动实现原先由 `panic!`负责的工作,即以非零错误码退出命令行工具的工作。非零的退出状态是一个惯例信号,用来告诉调用程序的进程:该程序以错误状态退出了。
<span class="filename">文件名src/main.rs</span>
@ -186,7 +186,7 @@
#### 从 `run` 函数中返回错误
通过将剩余的逻辑分离进 `run` 函数而不是留在 `main` 中,就可以像示例 12-9 中的 `Config::new` 那样改进错误处理。不再通过 `expect` 允许程序 panic`run` 函数将会在出错时返回一个 `Result<T, E>`。这让我们进一步以一种对用户友好的方式统一 `main` 中的错误处理。示例 12-12 展示了 `run` 签名和函数体中的改变:
通过将剩余的逻辑分离进 `run` 函数而不是留在 `main` 中,就可以像示例 12-9 中的 `Config::build` 那样改进错误处理。不再通过 `expect` 允许程序 panic`run` 函数将会在出错时返回一个 `Result<T, E>`。这让我们进一步以一种对用户友好的方式统一 `main` 中的错误处理。示例 12-12 展示了 `run` 签名和函数体中的改变:
<span class="filename">文件名src/main.rs</span>
@ -214,7 +214,7 @@ Rust 提示我们的代码忽略了 `Result` 值,它可能表明这里存在
#### 处理 `main``run` 返回的错误
我们将检查错误并使用类似示例 12-10 中 `Config::new` 处理错误的技术来处理他们,不过有一些细微的不同:
我们将检查错误并使用类似示例 12-10 中 `Config::build` 处理错误的技术来处理他们,不过有一些细微的不同:
<span class="filename">文件名src/main.rs</span>
@ -222,7 +222,7 @@ Rust 提示我们的代码忽略了 `Result` 值,它可能表明这里存在
{{#rustdoc_include ../listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs:here}}
```
我们使用 `if let` 来检查 `run` 是否返回一个 `Err` 值,不同于 `unwrap_or_else`,并在出错时调用 `process::exit(1)`。`run` 并不返回像 `Config::new` 返回的 `Config` 实例那样需要 `unwrap` 的值。因为 `run` 在成功时返回 `()`,而我们只关心检测错误,所以并不需要 `unwrap_or_else` 来返回未封装的值,因为它只会是 `()`
我们使用 `if let` 来检查 `run` 是否返回一个 `Err` 值,不同于 `unwrap_or_else`,并在出错时调用 `process::exit(1)`。`run` 并不返回像 `Config::build` 返回的 `Config` 实例那样需要 `unwrap` 的值。因为 `run` 在成功时返回 `()`,而我们只关心检测错误,所以并不需要 `unwrap_or_else` 来返回未封装的值,因为它只会是 `()`
不过两个例子中 `if let``unwrap_or_else` 的函数体都一样:打印出错误并退出。
@ -235,7 +235,7 @@ Rust 提示我们的代码忽略了 `Result` 值,它可能表明这里存在
- `run` 函数定义
- 相关的 `use` 语句
- `Config` 的定义
- `Config::new` 函数定义
- `Config::build` 函数定义
现在 *src/lib.rs* 的内容应该看起来像示例 12-13为了简洁省略了函数体。注意直到下一个示例修改完 *src/main.rs* 之后,代码还不能编译:

Loading…
Cancel
Save