@ -8,7 +8,7 @@
### 编写一个大小写不敏感 `search` 函数的失败测试
我们希望增加一个新函数 `search_case_insensitive` ,并将会在设置了 环境变量时调用它。这里将继续遵循 TDD 过程,其第一步是再次编写一个失败测试。我们将为新的大小写不敏感搜索函数新增一个测试函数,并将老的测试函数从 `one_result` 改名为 `case_sensitive` 来更清楚的表明这两个测试的区别,如示例 12-20 所示:
首先 我们希望增加一个新函数 `search_case_insensitive` ,并将会在环境变量有值 时调用它。这里将继续遵循 TDD 过程,其第一步是再次编写一个失败测试。我们将为新的大小写不敏感搜索函数新增一个测试函数,并将老的测试函数从 `one_result` 改名为 `case_sensitive` 来更清楚的表明这两个测试的区别,如示例 12-20 所示:
< span class = "filename" > 文件名: src/lib.rs< / span >
@ -38,7 +38,7 @@
注意 `query` 现在是一个 `String` 而不是字符串 slice, 因为调用 `to_lowercase` 是在创建新数据,而不是引用现有数据。如果查询字符串是 `"rUsT"` ,这个字符串 slice 并不包含可供我们使用的小写的 `u` 或 `t` ,所以必需分配一个包含 `"rust"` 的新 `String` 。现在当我们将 `query` 作为一个参数传递给 `contains` 方法时,需要增加一个 & 因为 `contains` 的签名被定义为获取一个字符串 slice。
接下来在检查每个 `line` 是否包含 `search` 之前增加了一个 `to_lowercase` 调用将他们都变 为小写。现在我们将 `line` 和 `query` 都转换成了小写,这样就可以不管查询的大小写进行匹配了。
接下来我们对每一 `line` 都调用 `to_lowercase` 将其转 为小写。现在我们将 `line` 和 `query` 都转换成了小写,这样就可以不管查询的大小写进行匹配了。
让我们看看这个实现能否通过测试:
@ -54,7 +54,7 @@
{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-22/src/lib.rs:here}}
```
这里增加了 ` case_sensitiv e` 字符来存放一个布尔值。接着我们需要 `run` 函数检查 `case_sensitive` 字段的值并使用它来决定是否调用 `search` 函数或 `search_case_insensitive` 函数,如示例 12-22 所示。注意这还不能编译:
这里增加了 ` ignore_ case` 字符来存放一个布尔值。接着我们需要 `run` 函数检查 `case_sensitive` 字段的值并使用它来决定是否调用 `search` 函数或 `search_case_insensitive` 函数,如示例 12-22 所示。注意这还不能编译:
< span class = "filename" > 文件名: src/lib.rs< / span >
@ -62,9 +62,9 @@
{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-22/src/lib.rs:there}}
```
< span class = "caption" > 示例 12-22: 根据 `config. case_sensitiv e` 的值调用 `search` 或 `search_case_insensitive` </ span >
< span class = "caption" > 示例 12-22: 根据 `config. ignore_ case` 的值调用 `search` 或 `search_case_insensitive` </ span >
最后需要实际检查环境变量。处理环境变量的函数位于标准库的 `env` 模块中,所以我们需要在 *src/lib.rs* 的开头增加一个 `use std::env;` 行 将这个模块引入作用域中。接着在 `Config::new` 中 使用 `env` 模块的 `var` 方法来检查一个叫做 ` IGNORE_CAS E` 的环境变量,如示例 12-23 所示:
最后需要实际检查环境变量。处理环境变量的函数位于标准库的 `env` 模块中,所以我们需要在 *src/lib.rs* 的开头将这个模块引入作用域中。接着使用 `env` 模块的 `var` 方法来检查一个叫做 ` CASE_INSENSITIV E` 的环境变量,如示例 12-23 所示:
< span class = "filename" > 文件名: src/lib.rs< / span >
@ -74,11 +74,11 @@
< span class = "caption" > 示例 12-23: 检查叫做 `IGNORE_CASE` 的环境变量</ span >
这里创建了一个新变量 ` case_sensitiv e`。为了设置它的值,需要调用 `env::var` 函数并传递我们需要寻找的环境变量名称,`IGNORE_CASE`。`env::var` 返回一个 `Result` ,它在环境变量被设置时返回包含其值的 `Ok` 成员,并在环境变量未被设置时返回 `Err` 成员。
这里创建了一个新变量 ` ignore_ case`。为了设置它的值,需要调用 `env::var` 函数并传递我们需要寻找的环境变量名称,`IGNORE_CASE`。`env::var` 返回一个 `Result` ,它在环境变量被设置时返回包含其值的 `Ok` 成员,并在环境变量未被设置时返回 `Err` 成员。
我们使用 `Result` 的 `is_err` 方法来检查其是否是一个 error( 也就是环境变量未被设置的情况) , 这也就意味着我们 ** 需要** 进行一个大小写敏感搜索。如果`IGNORE_CASE` 环境变量被设置为任何值,`is_err ` 会返回 false 并将进行大小写不敏感搜索。我们并不关心环境变量所设置的 ** 值**,只关心它是否被设置了,所以检查 `is_ err ` 而不是 `unwrap` 、`expect` 或任何我们已经见过的 `Result` 的方法。
我们使用 `Result` 的 `is_err` 方法来检查其是否是一个 error( 也就是环境变量未被设置的情况) , 这也就意味着我们 ** 需要** 进行一个大小写敏感搜索。如果`IGNORE_CASE` 环境变量被设置为任何值,`is_ok ` 会返回 false 并将进行大小写不敏感搜索。我们并不关心环境变量所设置的 ** 值**,只关心它是否被设置了,所以检查 `is_ ok ` 而不是 `unwrap` 、`expect` 或任何我们已经见过的 `Result` 的方法。
我们将变量 ` case_sensitiv e` 的值传递给 `Config` 实例,这样 `run` 函数可以读取其值并决定是否调用 `search` 或者示例 12-22 中实现的 `search_case_insensitive` 。
我们将变量 ` ignore_ case` 的值传递给 `Config` 实例,这样 `run` 函数可以读取其值并决定是否调用 `search` 或者示例 12-22 中实现的 `search_case_insensitive` 。
让我们试一试吧!首先不设置环境变量并使用查询 `to` 运行程序,这应该会匹配任何全小写的单词 “to” 的行:
@ -88,6 +88,10 @@
看起来程序仍然能够工作!现在将 `IGNORE_CASE` 设置为 `1` 并仍使用相同的查询 `to` 。
```console
$ IGNORE_CASE=1 cargo run to poem.txt
```
如果你使用 PowerShell, 则需要用两个命令来分别设置环境变量并运行程序:
```console
@ -97,9 +101,6 @@ PS> $Env:IGNORE_CASE=1; cargo run to poem.txt
这回应该得到包含可能有大写字母的 “to” 的行:
```console
$ (IGNORE_CASE=1; cargo run to poem.txt)
Finished dev [unoptimized + debuginfo] target(s) in 0.0s
Running `target/debug/minigrep to poem.txt`
Are you nobody, too?
How dreary to be somebody!
To tell your name the livelong day
@ -108,6 +109,6 @@ To an admiring bog!
好极了,我们也得到了包含 “To” 的行!现在 `minigrep` 程序可以通过环境变量控制进行大小写不敏感搜索了。现在你知道了如何管理由命令行参数或环境变量设置的选项了!
一些程序允许对相同配置同时使用参数 ** 和** 环境变量。在这种情况下,程序来决定参数和环境变量的优先级。作为一个留给你的测试,尝试通过一个命令行参数或一个环境变量来控制大小写不 敏感搜索。并在运行程序时遇到矛盾值时决定命令行参数和环境变量的优先级。
一些程序允许对相同配置同时使用参数 ** 和** 环境变量。在这种情况下,程序来决定参数和环境变量的优先级。作为一个留给你的测试,尝试通过一个命令行参数或一个环境变量来控制大小写敏感搜索。并在运行程序时遇到矛盾值时决定命令行参数和环境变量的优先级。
`std::env` 模块还包含了更多处理环境变量的实用功能;请查看官方文档来了解其可用的功能。