An IO Project Building a Command Line Program

Accepting Command Line Arguments

使用 std::env::args() 获得命令行参数迭代器

1
2
3
4
5
6
7
8
9
10
11
use std::env;

fn main() {
let args: Vec<String> = env::args().collect();
println!("{:#?}", args);
}

// output
[
"target\\debug\\rust.exe",
]

添加自定义参数

  1. cargo build
  2. cargo run -- command line

例如

1
2
3
4
5
6
7
8
cargo build
cargo run -- 2024 scut
// output
[
"target\\debug\\rust.exe",
"2024",
"scut",
]

Reading a File

在项目文件夹下添加 info.txt 添加内容, 利用 std::fs 读取文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// cargo build
// cargo run -- info.txt

use std::env;
use std::fs;

fn main() {
let args: Vec<String> = env::args().collect();
let path = &args[1];
let contents = fs::read_to_string(path).expect("error");

println!("{:#?}", args);
println!("{}", contents);
}

Refactoring to Improve Modularity and Error Handling

当我们在 main 不断添加内容, main 可能变得非常大, 这时候我们就要重构,改善模块

例如,将不同功能写到不同的函数, 添加更好的错误处理,对用户更好的错误提示等

例如将读取 path 改为一个函数

1
2
3
4
5
6
fn get_path(args: &[String]) -> &String {
if args.len() < 2 {
panic!("failed to get path");
}
&args[1]
}

Developing the Library’s Functionality with Test-Driven Development

  1. 编写一个失败的测试,并运行它以确保它失败的原因是你所期望的。
  2. 编写或修改足够的代码来使新的测试通过。
  3. 重构刚刚增加或修改的代码,并确保测试仍然能通过。
  4. 从步骤 1 开始重复!

Working with Environment Variables

通过 env::var() 来设置环境变量, 返回 Result , Ok 时表示其被设置

1
2
let ignore_case = env::var("IGNORE_CASE").is_ok();
// IGNORE_CASE=1 cargo run 将其设置为 1

Writing Error Messages to Standard Error Instead of Standard Output

将输出定向到文件中

1
cargo run > file

例如到 output.txt 中

1
cargo run > output.txt

eprintln!宏将错误打印到标准错误