I/O 项目:构建命令行程序
本章回顾了你到目前为止学到的许多技能,并探索了标准库的 I/O 功能。我们将构建一个命令行工具 —— 我们自己的 grep 版本 —— 来练习前面章节中的概念。
我们的 minigrep 项目将结合:
- 用
type和ext组织代码([第 7 章][ch7]) - 使用
List<T>和String([第 8 章][ch8]) - 用
!T和.collect()处理错误([第 9 章][ch9]) - 使用 spec([第 10 章][ch10])
- 编写测试([第 11 章][ch11])
接受命令行参数
使用 env.args() 读取命令行参数:
使用 `env.args()` 读取命令行参数
env.args() 返回命令行参数的迭代器。第一个参数始终是程序名本身。要收集它们到 List 中:
auto
let args = env.args().collect()注意:如果任何参数包含无效的 Unicode,
env.args()会 panic。 对于可能包含无效 Unicode 的参数,请使用env.args_os()。
读取文件
通过 use.rust 使用 Rust 标准库的 fs.read_to_string():
通过命令行参数读取文件
要点:
fn main() !—!返回类型启用错误传播fs.read_to_string(file_path).!— 读取文件,通过.collect()传播错误use env和use.rust std::fs— 导入环境和文件系统模块
重构以提高模块化
随着程序增长,我们将逻辑提取到单独的函数和 Config 类型中。这遵循了将二进制(main.rs)和库(lib.rs)代码分离的关注点分离惯例。
提取 Config 类型
模块化的 minigrep,包含 Config 类型和 search 函数
这个重构展示了几个重要的模式:
type Config— 将配置值分组到一个类型中Config.build()返回!Config— 在错误情况下使用throwfn run(config Config) !— 将程序逻辑与设置分离fn main() !— 保持简洁:构建配置、运行、处理错误.collect()用于!T— 等价于 Rust 的?运算符
环境变量
环境变量让用户无需更改命令行参数即可配置行为。使用 env.var("VAR_NAME"),它返回 !String:
环境变量实现大小写不敏感搜索
env.var("IGNORE_CASE") 返回 !String。.is_ok() 方法检查环境变量是否已设置(不管其值如何),返回 bool。
设置环境变量后运行:
console
$ IGNORE_CASE=1 automan run -- to poem.txt写入标准错误
使用 eprint() 输出错误消息(等价于 Rust 的 eprintln!):
auto
eprint("Error: file not found")这会将输出发送到 stderr 而非 stdout,这样用户可以将成功输出重定向到文件,同时仍然在屏幕上看到错误消息:
console
$ automan run -- query file.txt > results.txtI/O 速查
| 操作 | Auto | Rust |
|---|---|---|
| 命令行参数 | env.args() | std::env::args() |
| 读取文件 | fs.read_to_string(path).! | std::fs::read_to_string(path)? |
| 环境变量 | env.var("KEY") | std::env::var("KEY") |
| 检查环境变量 | env.var("KEY").is_ok() | std::env::var("KEY").is_ok() |
| 标准输出 | print() | println!() |
| 标准错误 | eprint() | eprintln!() |
| 退出码 | sys.exit(code) | std::process::exit(code) |
总结
本章演示了用 Auto 构建一个完整的命令行程序:
- 用
env.args()接受命令行参数 - 用
use.rust std::fs和fs.read_to_string()读取文件 - 用
type Config和分离的search/run函数 组织代码 - 用
!T返回类型和.collect()传播 处理错误 - 用
env.var()使用环境变量 - 用
eprint()写入标准错误
该项目结合了前面每一章的概念:类型、扩展、集合、错误处理、spec、泛型和测试。
在下一章中,我们将探索函数式语言特性:闭包和迭代器。