# [一个I/O项目:构建一个命令行程序](../minigrep/src/main.rs) ## 二进制项目的关注分离 main 函数负责多个任务的组织问题在许多二进制项目中很常见。所以Rust社区开发出一类在main函数开始变得庞大时进行二进制程序的关注分离的指导性过程。这些过程有如下步骤: - 将程序拆分成main.rs和lib.rs并将程序的逻辑放入lib.rs - 当程序逻辑比较小时,可以保留在main.rs中 - 当程序逻辑开始变得复杂时,将其从main.rs中移出到lib.rs中 经过这些过程之后保留在main函数中的责任应该被限制为: - 使用参数值调用命令行解析逻辑 - 设置其他的配置 - 调用lib.rs中的run函数 - 如果run返回错误,则处理这个错误 这个模式的一切就是为了关注分离:main.rs处理程序运行,而lib.rs处理所有真正的任务逻辑。因为不能直接测试main函数,这个结构通过将所有的程序逻辑移动到lib.rs的函数中使得我们可以测试他们。仅仅保留在main.rs中的代码将足够小以便阅读就可以验证其正确性。 ## 采用测试驱动开发完善库的功能 测试驱动开发(Test Driven Development, TDD)的模式来逐步增加minigrep的搜索逻辑。这是一个软件开发技术,它遵循如下步骤: 1. 编写一个失败的测试,并运行它以确保它失败的原因时你所期望的。 2. 编写或修改足够的代码来使测试通过。 3. 重构刚刚增加或修改的代码,并确保测试任然能通过。 4. 从步骤1开始重复! 这只是众多编写软件的方法之一,不过TDD有助于驱动代码的设计。在编写能使测试通过的代码之前编写的测试有助于在开发过程中保持高测试覆盖率。 ## 处理环境变量 一个注意点:使用`env`设置临时环境变量的时候,要想在`std::env::vars()`获取到设置的环境变量,设置语句和运行语句要同时执行: ```shell env CASE_INSENSITIVE=1 cargo run to poem.txt ``` ## 将错误信息输出到标准错误而不是标准输出 大部分终端都提供了两种输出:标准输出(standard output, stdout)对应一般信息,标准错误(standard error, stderr)则用于错误信息。这种区别允许用户选择将程序正常输出重定向到一个文件中并任将错误信息打印到屏幕上。 但是`println!()`宏只能够打印到标准输出,所以我们需要使用`eprintln!()`宏来打印到标准错误。