知用网
白蓝主题五 · 清爽阅读
首页  > 软件入门

Rust项目实战:从零开始做一个命令行小工具

为什么选ref="/tag/2030/" style="color:#643D3D;font-weight:bold;">Rust做小项目

刚学完Rust语法,书上的例子都太简单,想动手又不知道做什么。其实最好的练手方式就是写个能用的小工具。比如你每天都要查天气、记待办事项,与其打开网页或App,不如自己写个命令行程序,敲一行命令就出结果,既实用又有成就感。

Rust虽然以系统编程著称,但它的包管理器Cargo和丰富的crate生态,也能让你快速搭出功能完整的应用。而且编译成单个二进制文件后,扔给朋友直接运行,连安装都不需要。

目标:一个简易备忘录

咱们做一个叫memo的命令行工具,能保存短文本,带标签分类,还能按标签查找。比如:

memo add "买牛奶" -t 购物
memo list -t 购物

输出应该是:

- 买牛奶

初始化项目

打开终端,输入:

cargo new memo
cd memo

生成的src/main.rs就是主文件。现在它还啥都不能干,我们一步步加功能。

读取命令行参数

在Cargo.toml里加个依赖:

[dependencies]
clap = { version = "4.0", features = ["derive"] }

clap是个很流行的命令行解析库。然后改main.rs:

use clap::Parser;

#[derive(Parser)]
struct Cli {
#[command(subcommand)]
command: Commands,
}

#[derive(clap::Subcommand)]
enum Commands {
Add {
text: String,
#[arg(short, long)]
tag: Option<String>,
},
List {
#[arg(short, long)]
tag: Option<String>,
},
}

这样就能解析add和list子命令了。接下来处理逻辑。

保存数据到文件

数据存哪?不用数据库,就用个JSON文件。再加个依赖:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

定义一个结构体存每条记录:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Item {
text: String,
tag: String,
}

读写文件的函数:

fn read_items() -> Vec<Item> {
let file = std::fs::File::open("items.json").unwrap_or_else(|_| {
std::fs::write("items.json", "[]").expect("无法创建文件");
std::fs::File::open("items.json").unwrap()
});
serde_json::from_reader(file).unwrap_or_else(|_| vec![])
}

fn save_items(items: &[Item]) {
let json = serde_json::to_string_pretty(items).expect("序列化失败");
std::fs::write("items.json", json).expect("写入失败");
}

拼起来跑一跑

在main函数里处理命令:

let cli = Cli::parse();
let mut items = read_items();

match &cli.command {
Commands::Add { text, tag } => {
items.push(Item {
text: text.clone(),
tag: tag.clone().unwrap_or_default(),
});
save_items(&items);
println!("已添加");
}
Commands::List { tag } => {
let filtered: Vec<&Item> = items.iter().filter(|i| {
tag.as_ref().map_or(true, |t| t == &i.tag)
}).collect();
for item in filtered {
println!("- {}", item.text);
}
}
}

现在执行cargo run -- add "倒垃圾" -t 家务,再执行cargo run -- list -t 家务,就能看到输出了。

还能怎么改进

这个小工具虽然简单,但已经涵盖了实际开发的几个关键点:命令行解析、数据持久化、错误处理。你可以继续加功能,比如删除条目、支持优先级、导出为CSV。每次加新功能,都会加深对Rust所有权、Result处理的理解。

别小看这种“玩具项目”,它比抄语法示例强多了。当你真正在用自己写的程序时,那种感觉是不一样的。下回同事问你怎么记住每日任务的,你说我用自己写的Rust工具,绝对有面儿。