improve some translation and fix typo in ch12

pull/279/head
Lam 6 years ago
parent de8b4cc84b
commit f2b39f5f64

@ -1,4 +1,4 @@
## 接受命令行参数
## 接受命令行参数
> [ch12-01-accepting-command-line-arguments.md](https://github.com/rust-lang/book/blob/master/src/ch12-01-accepting-command-line-arguments.md)
> <br>
@ -45,9 +45,9 @@ fn main() {
>
> 注意 `std::env::args` 在其任何参数包含无效 Unicode 字符时会 panic。如果你需要接受包含无效 Unicode 字符的参数,使用 `std::env::args_os` 代替。这个函数返回 `OsString` 值而不是 `String` 值。这里出于简单考虑使用了 `std::env::args`,因为 `OsString` 值每个平台都不一样而且比 `String` 值处理起来更为复杂。
`main` 函数的第一行,我们调用了 `env::args`,并立即使用 `collect` 来创建了一个包含迭代器所有值的 vector。`collect` 可以被用来创建很多类型的集合,所以这里显式注明 `args` 的类型来指定我们需要一个字符串 vector。虽然在 Rust 中我们很少会需要注明类型,`collect` 是一个经常需要注明类型的函数,因为 Rust 不能推断出你想要什么类型的集合。
`main` 函数的第一行,我们调用了 `env::args`,并立即使用 `collect` 来创建了一个包含迭代器所有值的 vector。`collect` 可以被用来创建很多类型的集合,所以这里显式注明 `args` 的类型来指定我们需要一个字符串 vector。虽然在 Rust 中我们很少会需要注明类型,然而 `collect` 是一个经常需要注明类型的函数,因为 Rust 不能推断出你想要什么类型的集合。
最后,我们使用调试格式 `:?` 打印出 vector。让我们尝试不用参数运行代码,接着用两个参数
最后,我们使用调试格式 `:?` 打印出 vector。让我们尝试分别用两种方式(不包含参数和包含参数)运行代码
```text
$ cargo run

@ -1,4 +1,4 @@
## 读取文件
## 读取文件
> [ch12-02-reading-a-file.md](https://github.com/rust-lang/book/blob/master/src/ch12-02-reading-a-file.md)
> <br>
@ -49,11 +49,11 @@ fn main() {
<span class="caption">示例 12-4读取第二个参数所指定的文件内容</span>
首先,我们增加了更多的 `use` 语句来引入标准库中的相关部分:需要 `std::fs` 来处理文件。
首先,我们增加了一个 `use` 语句来引入标准库中的相关部分:我们需要 `std::fs` 来处理文件。
`main` 中新增了一行语句:`fs::read_to_string` 接受 `filename`,打开文件,接着返回包含其内容的 `Result<String>`
在这些代码之后,我们再次增加了临时的 `println!` 打印出读取文件后 `contents` 的值,这样就可以检查目前为止的程序能否工作。
在这些代码之后,我们再次增加了临时的 `println!` 打印出读取文件`contents` 的值,这样就可以检查目前为止的程序能否工作。
尝试运行这些代码,随意指定一个字符串作为第一个命令行参数(因为还未实现搜索功能的部分)而将 *poem.txt* 文件将作为第二个参数:

@ -1,4 +1,4 @@
## 重构改进模块性和错误处理
## 重构改进模块性和错误处理
> [ch12-03-improving-error-handling-and-modularity.md](https://github.com/rust-lang/book/blob/master/src/ch12-03-improving-error-handling-and-modularity.md)
> <br>
@ -10,7 +10,7 @@
这同时也关系到第二个问题:`search` 和 `filename` 是程序中的配置变量,而像 `f``contents` 则用来执行程序逻辑。随着 `main` 函数的增长,就需要引入更多的变量到作用域中,而当作用域中有更多的变量时,将更难以追踪每个变量的目的。最好能将配置变量组织进一个结构,这样就能使他们的目的更明确了。
第三个问题是如果打开文件失败我们使用 `expect` 来打印出错误信息,不过这个错误信息只是说 `file not found`。除了缺少文件之外还有很多打开文件可能失败的方式:例如,文件可能存在,不过可能没有打开它的权限。如果我们现在就出于这种情况,打印出的 `file not found` 错误信息就给了用户错误的建议!
第三个问题是如果打开文件失败我们使用 `expect` 来打印出错误信息,不过这个错误信息只是说 `file not found`。除了缺少文件之外还有很多可以导致打开文件失败的方式:例如,文件可能存在,不过可能没有打开它的权限。如果我们现在就出于这种情况,打印出的 `file not found` 错误信息就给了用户错误的建议!
第四,我们不停的使用 `expect` 来处理不同的错误,如果用户没有指定足够的参数来运行程序,他们会从 Rust 得到 `index out of bounds` 错误,而这并不能明确的解释问题。如果所有的错误处理都位于一处这样将来的维护者在需要修改错误处理逻辑时就只需要考虑这一处代码。将所有的错误处理都放在一处也有助于确保我们打印的错误信息对终端用户来说是有意义的。
@ -106,7 +106,7 @@ fn parse_config(args: &[String]) -> Config {
<span class="caption">示例 12-6重构 `parse_config` 返回一个 `Config` 结构体实例</span>
`parse_config` 的签名表明它现在返回一个 `Config` 值。在 `parse_config` 的函数体中,之前返回引用了 `args``String` 值的字符串 slice现在我们选择定义 `Config` 来包含拥有所有权的 `String` 值。`main` 中的 `args` 变量是参数值的所有者并只允许 `parse_config` 函数借用他们,这意味着如果 `Config` 尝试获取 `args` 中值的所有权将违反 Rust 的借用规则。
`parse_config` 的签名表明它现在返回一个 `Config` 值。在之前的 `parse_config` 函数体中,我们返回了引用 `args``String` 值的字符串 slice现在我们定义 `Config` 来包含拥有所有权的 `String` 值。`main` 中的 `args` 变量是参数值的所有者并只允许 `parse_config` 函数借用他们,这意味着如果 `Config` 尝试获取 `args` 中值的所有权将违反 Rust 的借用规则。
还有许多不同的方式可以处理 `String` 的数据,而最简单但有些不太高效的方式是调用这些值的 `clone` 方法。这会生成 `Config` 实例可以拥有的数据的完整拷贝,不过会比储存字符串数据的引用消耗更多的时间和内存。不过拷贝数据使得代码显得更加直白因为无需管理引用的生命周期,所以在这种情况下牺牲一小部分性能来换取简洁性的取舍是值得的。
@ -330,7 +330,7 @@ fn run(config: Config) -> Result<(), Box<dyn Error>> {
这里我们做出了三个明显的修改。首先,将 `run` 函数的返回类型变为 `Result<(), Box<Error>>`。之前这个函数返回 unit 类型 `()`,现在它仍然保持作为 `Ok` 时的返回值。
对于错误类型,使用了 **trait 对象** `Box<dyn Error>`(在开头使用了 `use` 语句将 `std::error::Error` 引入作用域)。第十七章会涉及 trait 对象。目前只需知道 `Box<dyn Error>` 意味着函数会返回实现了 `Error` trait 的类型,不过无需指定具体将会返回的值的类型。这提供了在不同的错误场景可能有不同类型的错误返回值的灵活性。这也就是 `dyn`,它是 “动态”“dynamic”的缩写。
对于错误类型,使用了 **trait 对象** `Box<dyn Error>`(在开头使用了 `use` 语句将 `std::error::Error` 引入作用域)。第十七章会涉及 trait 对象。目前只需知道 `Box<dyn Error>` 意味着函数会返回实现了 `Error` trait 的类型,不过无需指定具体将会返回的值的类型。这提供了在不同的错误场景可能有不同类型的错误返回值的灵活性。这也就是 `dyn`,它是 “动态“dynamic”的缩写。
第二个改变是去掉了 `expect` 调用并替换为第九章讲到的 `?`。不同于遇到错误就 `panic!``?` 会从函数中返回错误值并让调用者来处理它。
@ -434,8 +434,8 @@ fn main() {
<span class="caption">示例 12-14`minigrep` crate 引入 *src/main.rs* 的作用域中</span>
为了将库 crate 引入二进制 crate我们使用 `extern crate minigrep`。接着增加 `use minigrep::Config``Config` 类型引入作用域,并使用 crate 名作为 `run` 函数的前缀。通过这些重构,所有功能应该能够联系在一起并运行了。运行 `cargo run` 来确保一切都正确的衔接在一起。
为了将库 crate 引入二进制 crate我们使用`use minigrep`。接着 `use minigrep::Config``Config` 类型引入作用域,并使用 crate 名作为 `run` 函数的前缀。通过这些重构,所有功能应该能够联系在一起并运行了。运行 `cargo run` 来确保一切都正确的衔接在一起。
哇哦!这可有很多的工作,不过我们为将来的成功打下了基础。现在处理错误将更容易,同时代码也更加模块化。从现在开始几乎所有的工作都将在 *src/lib.rs* 中进行。
让我们利用这些新创建的模块的优势来进行一些在旧代码中难以展开的工作,他们在新代码中却很简单:编写测试!
让我们利用这些新创建的模块的优势来进行一些在旧代码中难以展开的工作,这些工作在新代码中非常容易实现,那就是:编写测试!

@ -1,4 +1,4 @@
## 采用测试驱动开发完善库的功能
## 采用测试驱动开发完善库的功能
> [ch12-04-testing-the-librarys-functionality.md](https://github.com/rust-lang/book/blob/master/src/ch12-04-testing-the-librarys-functionality.md)
> <br>

@ -1,10 +1,10 @@
## 处理环境变量
## 处理环境变量
> [ch12-05-working-with-environment-variables.md](https://github.com/rust-lang/book/blob/master/src/ch12-05-working-with-environment-variables.md)
> <br>
> commit 1fedfc4b96c2017f64ecfcf41a0a07e2e815f24f
我们将增加一个额外的功能来改进 `minigrep`一个通过环境变量启用的大小写不敏感搜索的选项。可以将其设计为一个命令行参数并要求用户每次需要时都加上它,不过相反我们将使用环境变量。这允许用户设置环境变量一次之后在整个终端会话中所有的搜索都将是大小写不敏感的。
我们将增加一个额外的功能来改进 `minigrep`用户可以通过设置环境变量来设置搜索是否是大小写敏感的 。当然,我们也可以将其设计为一个命令行参数并要求用户每次需要时都加上它,不过在这里我们将使用环境变量。这允许用户设置环境变量一次之后在整个终端会话中所有的搜索都将是大小写不敏感的。
### 编写一个大小写不敏感 `search` 函数的失败测试
@ -199,7 +199,7 @@ How dreary to be somebody!
看起来程序仍然能够工作!现在将 `CASE_INSENSITIVE` 设置为 `1` 并仍使用相同的查询 `to`
如果你使用 PowerShell则需要用两句命令而不是一句来设置环境变量并运行程序:
如果你使用 PowerShell则需要用两个命令来设置环境变量并运行程序:
```text
$ $env:CASE_INSENSITIVE=1

@ -1,4 +1,4 @@
## 将错误信息输出到标准错误而不是标准输出
## 将错误信息输出到标准错误而不是标准输出
> [ch12-06-writing-to-stderr-instead-of-stdout.md](https://github.com/rust-lang/book/blob/master/src/ch12-06-writing-to-stderr-instead-of-stdout.md)
> <br>
@ -10,11 +10,11 @@
### 检查错误应该写入何处
首先,让我们观察一下目前 `minigrep` 打印的所有内容都被写入了标准输出,包括应该被写入标准错误的错误信息。可以通过将标准输出流重定向到一个文件同时有意产生一个错误来做到这一点。我们没有重定向标准错误流,所以任何发送到标准错误的内容将会继续显示在屏幕上。
首先,让我们观察一下目前 `minigrep` 打印的所有内容是如何被写入标准输出的,包括那些应该被写入标准错误的错误信息。可以通过将标准输出流重定向到一个文件同时有意产生一个错误来做到这一点。我们没有重定向标准错误流,所以任何发送到标准错误的内容将会继续显示在屏幕上。
命令行程序被期望将错误信息发送到标准错误流,这样即便选择将标准输出流重定向到文件中时仍然能看到错误信息。目前我们的程序并不符合期望;相反我们将看到它将错误信息输出保存到了文件中。
展示这种行为的方式是通过 `>` 和文件名 *output.txt* 来与运行程序,这个文件是期望重定向标准输出流的位置。并不传递任何参数应该会产生一个错误:
我们通过 `>` 和文件名 *output.txt* 来运行程序,我们期望重定向标准输出流到该文件中。在这里,我们没有传递任何参数,所以会产生一个错误:
```text
$ cargo run > output.txt
@ -26,7 +26,7 @@ $ cargo run > output.txt
Problem parsing arguments: not enough arguments
```
是的,错误信息被打印到了标准输出中。像这样的错误信息被打印到标准错误中将有用的多,并在重定向标准输出时只将成功运行的信息写入文件。我们将改变他们
是的,错误信息被打印到了标准输出中。像这样的错误信息被打印到标准错误中将会有用的多,并且只将成功运行的信息写入文件。接下来我们将对程序进行修改从而以这种方式进行输出
### 将错误打印到标准错误

Loading…
Cancel
Save