
10 命令行程序
之前test中已经提到过,cargo通过—区分两段参数,前一段是给cargo的,后一段是给将要运行的命令程序的。
env标准库
std::env::args函数,这个函数返回一个传递给程序的命令行参数的迭代器(iterator)。let args: Vec<String> = env::args().collect();
首先使用 use 语句来将 std::env 模块引入作用域以便可以使用它的 args 函数。当所需函数嵌套了多于一层
模块时,通常将父模块引入作用域而不是其自身。这便于我们利用 std::env 中的其他函数。==而且能避免args被错认为是定义为当前模块的函数。==
如果你需要接受包含无效 Unicode 字符的参数,使用 std::env::args_os 代替。这个函数返回OsString 值而不是 String 值。
因为 Rust 不能推断出你想要什么类型的集合,vector、map、set都可以存储。
只是名称,并非全路径,不过这个名称似乎与相对路径有关,似乎能从名称中找到命令被调用的路径,以及程序运行的“当前目录”
std::env::fs::read_to_string 接受 file_path ,打开文件,接着返回包含
其内容的std::io::Result<String>
重构来改进
重构操作的目标有这么几个:
1 修复问题
2 分离功能
3 变量组织
4 错误处理
5 模块化
每个函数最好只承担一个功能,就算是调用层,宏观或者栈底层函数,也需要有自己清楚的定位。
这样出问题之后可以通过哪个函数出问题从而知道大概是什么功能的问题。
零散的变量非常难以理解,将变量通过逻辑关系捆绑起来,让命名空间更清楚、代码联想、生命周期都更容易管理。
错误处理是代码的重要功能,将错误的原因以及解决办法清楚的显示这是错误处理的目标。
将程序拆分成main.rs以及lib.rs,程序逻辑分成不同的模块。这样更好重用代码。代码联想也更容易。
我们可以将 parse_config 从一个普通函数变为一个叫做 new 的与结构体关联的函数。这样更符合创建的含义。
相比于使用match,更加优雅。
如何理解这个名字呢?unwrap_or部分表示解包失败,else部分表示执行代码来处理。
例如.unwrap_or_else()的意图是处理error让Ok()主线为主流。
在大学的时候,我自己开发毕业设计的时候就意识到了测试驱动开发,
后来才发现原来已经有这样的概念了。
测试驱动开发确实厉害,但是写测试确实有点恼火哈哈,没有成就感。
但是需要通过\转义换行符,这样在实际字符串中会忽略换行符的存在。
处理环境变量
std::env::var(“变量名”)将会得到一个Result,为了体现我们的主要思路,直接使用is_ok()表示检测是否存在即可,而不是通过except,wrap等。
标准输出
我们知道shell中可以通过重定向将标准输出流重定向到文件中。1 Shell
此时的标准错误流仍然会显示在屏幕上。所以如果我们不把打印信息加以区分,那么就无法实现这个功能。
println! stdout 正常程序输出
eprintln! stderr 错误、警告、提示
dbg! stderr 调试打印
