diff --git a/src/ch12-03-improving-error-handling-and-modularity.md b/src/ch12-03-improving-error-handling-and-modularity.md index 5ce3006..2e2647d 100644 --- a/src/ch12-03-improving-error-handling-and-modularity.md +++ b/src/ch12-03-improving-error-handling-and-modularity.md @@ -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}} ``` -示例 12-9:从 `Config::new` 中返回 `Result` +示例 12-9:从 `Config::build` 中返回 `Result` -现在 `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!`负责的工作,即以非零错误码退出命令行工具的工作。非零的退出状态是一个惯例信号,用来告诉调用程序的进程:该程序以错误状态退出了。 文件名:src/main.rs @@ -186,7 +186,7 @@ #### 从 `run` 函数中返回错误 -通过将剩余的逻辑分离进 `run` 函数而不是留在 `main` 中,就可以像示例 12-9 中的 `Config::new` 那样改进错误处理。不再通过 `expect` 允许程序 panic,`run` 函数将会在出错时返回一个 `Result`。这让我们进一步以一种对用户友好的方式统一 `main` 中的错误处理。示例 12-12 展示了 `run` 签名和函数体中的改变: +通过将剩余的逻辑分离进 `run` 函数而不是留在 `main` 中,就可以像示例 12-9 中的 `Config::build` 那样改进错误处理。不再通过 `expect` 允许程序 panic,`run` 函数将会在出错时返回一个 `Result`。这让我们进一步以一种对用户友好的方式统一 `main` 中的错误处理。示例 12-12 展示了 `run` 签名和函数体中的改变: 文件名:src/main.rs @@ -214,7 +214,7 @@ Rust 提示我们的代码忽略了 `Result` 值,它可能表明这里存在 #### 处理 `main` 中 `run` 返回的错误 -我们将检查错误并使用类似示例 12-10 中 `Config::new` 处理错误的技术来处理他们,不过有一些细微的不同: +我们将检查错误并使用类似示例 12-10 中 `Config::build` 处理错误的技术来处理他们,不过有一些细微的不同: 文件名:src/main.rs @@ -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* 之后,代码还不能编译: