一、项目总览
项目背景与价值
在语言学习中,「高频复习 + 个性化积累」是掌握单词的核心方法,但市面上多数单词 APP 存在广告冗余、功能繁杂、依赖网络等问题。本项目基于 Rust 标准库开发一款零依赖本地单词本,无需网络、无广告干扰、数据完全自主掌控,支持单词的增删查改、分类标签、复习测试等核心功能,兼顾实用性与学习价值。
核心功能清单
|------|----------------------------------------------|
| 功能模块 | 具体能力 |
| 基础操作 | 添加单词(英文 + 中文 + 音标)、查询单词(精确 / 模糊匹配)、修改单词、删除单词 |
| 分类管理 | 给单词添加标签(如「CET-4」「日常交流」)、按标签筛选单词 |
| 数据管理 | 本地持久化存储(纯文本格式,可手动编辑)、数据备份 / 恢复 |
| 复习测试 | 随机抽查单词、中文→英文默写模式、正确率统计 |
| 辅助功能 | 单词排序(字母序 / 添加时间序)、批量删除、清空单词本(二次确认) |
技术选型与优势
- 开发语言:Rust 1.70.0+(Edition 2021)
- 技术栈:仅使用 Rust 标准库(
<font style="background-color:rgb(187,191,196);">std::fs</font>文件操作、<font style="background-color:rgb(187,191,196);">std::io</font>输入输出、<font style="background-color:rgb(187,191,196);">std::collections</font>数据结构) - 核心优势:
-
- 零第三方依赖:无需下载任何额外包,编译速度快,无网络依赖
- 跨平台兼容:自动适配 Windows/macOS/Linux,文件格式通用
- 数据安全:所有数据存储在本地纯文本文件,支持手动备份与编辑
- 轻量高效:体积小、启动快,无后台进程,资源占用低
二、环境搭建与项目初始化
前置环境验证
确保本地已安装 Rust 工具链,打开终端执行以下命令验证:
rustc --version # 需输出 1.70.0 及以上版本
cargo --version # 需输出对应版本的 Cargo 包管理器
未安装则前往 Rust 官网 下载 <font style="background-color:rgb(187,191,196);">rustup-init</font> 一键安装(默认配置即可)。
项目创建与结构设计
步骤 1:创建项目
# 创建项目目录并初始化
cargo new rust_local_vocab_pro
cd rust_local_vocab_pro
步骤 2:项目结构说明
采用「单文件核心 + 本地数据文件」结构,无复杂模块拆分,便于维护与修改:
rust_local_vocab_pro/
├── Cargo.toml # 项目配置(默认生成,无需额外依赖)
├── vocab_data.txt # 单词数据存储文件(自动生成)
├── vocab_backup.txt # 数据备份文件(手动触发生成)
└── src/
└── main.rs # 核心逻辑文件(所有功能实现)
步骤 3:配置 <font style="background-color:rgb(187,191,196);">Cargo.toml</font>
无需添加任何第三方依赖,默认生成的配置即可满足需求,完整内容如下:
[package]name = "rust_local_vocab_pro"version = "0.1.0"edition = "2021"description = "零依赖本地多功能单词本,支持增删查改、分类标签、复习测试"license = "MIT"# 无需任何 dependencies 配置,仅使用标准库
三、核心数据结构设计
单词结构体(核心模型)
设计支持多字段的 <font style="background-color:rgb(187,191,196);">Word</font> 结构体,包含英文、中文、音标、标签、添加时间等关键信息,同时实现 <font style="background-color:rgb(187,191,196);">Clone</font> 和 <font style="background-color:rgb(187,191,196);">PartialEq</font> 特性以支持复制和比较:
use std::fmt;use std::time::{SystemTime, UNIX_EPOCH};// 单词结构体:包含核心字段与元数据#[derive(Debug, Clone, PartialEq)]struct Word {
english: String, // 英文单词
chinese: String, // 中文释义
phonetic: String, // 音标(可选)
tags: Vec<String>, // 标签(支持多个,如 ["CET-4", "高频"])
add_time: u64, // 添加时间(时间戳,用于排序)
review_count: u32, // 复习次数(用于优先级排序)
correct_count: u32, // 测试正确次数(用于正确率统计)}// 实现 fmt::Display 特性,便于格式化输出impl fmt::Display for Word {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {let tags_str = if self.tags.is_empty() {"无标签".to_string()} else {self.tags.join("、")};let phonetic_str = if self.phonetic.is_empty() {"无音标".to_string()} else {format!("/{}", self.phonetic)};let accuracy = if self.review_count == 0 {"0%".to_string()} else {format!("{:.1}%", (self.correct_count as f64 / self.review_count as f64) * 100.0)};write!(
f,"英文:{} {}\n中文:{}\n标签:{}\n复习:{}次(正确率:{})",self.english, phonetic_str, self.chinese, tags_str, self.review_count, accuracy
)}}// 辅助函数:获取当前时间戳(用于单词添加时间)fn get_current_timestamp() -> u64 {SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()}
数据存储格式设计
采用「一行一个单词」的纯文本格式,字段间用 <font style="background-color:rgb(187,191,196);">|||</font> 分隔(避免与单词内容冲突),具体格式如下:
apple|||苹果;苹果树|||/ˈæpl/|||CET-4、日常|||1730000000|||3|||2
各字段对应关系:
- 英文单词 →
<font style="background-color:rgb(187,191,196);">apple</font> - 中文释义 →
<font style="background-color:rgb(187,191,196);">苹果;苹果树</font> - 音标 →
<font style="background-color:rgb(187,191,196);">/ˈæpl/</font>(空值表示无音标) - 标签 →
<font style="background-color:rgb(187,191,196);">CET-4、日常</font>(多个标签用「、」分隔) - 添加时间戳 →
<font style="background-color:rgb(187,191,196);">1730000000</font> - 复习次数 →
<font style="background-color:rgb(187,191,196);">3</font> - 正确次数 →
<font style="background-color:rgb(187,191,196);">2</font>
这种格式的优势:
- 人类可读,支持用记事本直接编辑
- 字段分隔符不易冲突,兼容性强
- 无需解析库,标准库字符串处理即可解析
四、核心功能实现
数据持久化模块(文件读写)
负责单词数据的加载、保存、备份与恢复,是所有功能的基础:
use std::fs;use std::path::Path;// 数据文件路径常量(统一管理,便于修改)const DATA_FILE: &str = "vocab_data.txt";const BACKUP_FILE: &str = "vocab_backup.txt";/// 加载本地单词数据fn load_words() -> Vec<Word> {// 检查数据文件是否存在,不存在则返回空列表if !Path::new(DATA_FILE).exists() {return Vec::new();}// 读取文件内容let content = fs::read_to_string(DATA_FILE).expect(&format!("读取单词数据失败,请检查 {} 文件是否正常", DATA_FILE));// 按行解析单词(跳过空行)
content
.lines().filter(|line| !line.trim().is_empty()).map(|line| parse_word_line(line)).collect()}/// 解析单行单词数据为 Word 结构体fn parse_word_line(line: &str) -> Word {let parts: Vec<&str> = line.split("|||").collect();// 确保字段数量正确,缺失字段用默认值填充let english = parts.get(0).map(|s| s.trim().to_string()).unwrap_or_default();let chinese = parts.get(1).map(|s| s.trim().to_string()).unwrap_or_default();let phonetic = parts.get(2).map(|s| s.trim().to_string()).unwrap_or_default();let tags = parts
.get(3).map(|s| s.split('、').map(|t| t.trim().to_string()).filter(|t| !t.is_empty()).collect()).unwrap_or_default();let add_time = parts.get(4).map(|s| s.parse().unwrap_or(0)).unwrap_or(0);let review_count = parts.get(5).map(|s| s.parse().unwrap_or(0)).unwrap_or(0);let correct_count = parts.get(6).map(|s| s.parse().unwrap_or(0)).unwrap_or(0);Word {
english,
chinese,
phonetic,
tags,
add_time,
review_count,
correct_count,}}/// 保存单词数据到本地文件fn save_words(words: &[Word]) {// 将所有单词转换为字符串(按格式拼接)let content: String = words
.iter().map(|word| format_word_line(word)).collect();// 写入文件(覆盖原有内容)fs::write(DATA_FILE, content).expect(&format!("保存单词数据失败,请检查 {} 文件权限", DATA_FILE));}/// 将 Word 结构体转换为单行字符串fn format_word_line(word: &Word) -> String {let tags_str = word.tags.join("、");format!("{|||}{|||}{|||}{|||}{|||}{|||}\n",
word.english, word.chinese, word.phonetic, tags_str, word.add_time, word.review_count, word.correct_count
)}/// 备份单词数据(生成备份文件)fn backup_words(words: &[Word]) {let content: String = words
.iter().map(|word| format_word_line(word)).collect();fs::write(BACKUP_FILE, content).expect(&format!("备份单词数据失败,请检查 {} 文件权限", BACKUP_FILE));println!("✅ 数据备份成功!备份文件:{}", BACKUP_FILE);}/// 从备份文件恢复数据fn restore_words() -> Result<Vec<Word>, String> {if !Path::new(BACKUP_FILE).exists() {return Err(format!("备份文件不存在:{}", BACKUP_FILE));}let content = fs::read_to_string(BACKUP_FILE).map_err(|e| format!("读取备份文件失败:{}", e))?;let words: Vec<Word> = content
.lines().filter(|line| !line.trim().is_empty()).map(|line| parse_word_line(line)).collect();if words.is_empty() {return Err("备份文件为空,无法恢复".to_string());}// 覆盖当前数据文件save_words(&words);Ok(words)}
单词基础操作模块(增删查改)
实现单词的添加、查询、修改、删除核心功能,支持交互式输入与命令行参数两种操作方式:
use std::io;/// 添加新单词(交互式输入)fn add_word(words: &mut Vec<Word>) {println!("\n📥 添加新单词");println!("{}", "-".repeat(40));// 输入英文单词(必填)let english = prompt_input("请输入英文单词(必填):", true);// 检查单词是否已存在(忽略大小写)if words.iter().any(|w| w.english.eq_ignore_ascii_case(&english)) {eprintln!("❌ 错误:单词「{}」已存在,无需重复添加", english);return;}// 输入中文释义(必填)let chinese = prompt_input("请输入中文释义(必填):", true);// 输入音标(可选)let phonetic = prompt_input("请输入音标(可选,如 /ˈæpl/):", false);// 输入标签(可选,多个用逗号分隔)let tags_input = prompt_input("请输入标签(可选,多个用逗号分隔,如 CET-4,日常):", false);let tags: Vec<String> = tags_input
.split(',').map(|t| t.trim().to_string()).filter(|t| !t.is_empty()).collect();// 创建单词实例let new_word = Word {
english: english.trim().to_string(),
chinese: chinese.trim().to_string(),
phonetic: phonetic.trim().to_string(),
tags,
add_time: get_current_timestamp(),
review_count: 0,
correct_count: 0,};// 添加到单词列表并保存
words.push(new_word.clone());save_words(words);println!("\n✅ 单词添加成功!");println!("{}", "-".repeat(40));println!("{}", new_word);}/// 交互式输入提示(支持必填校验)fn prompt_input(prompt: &str, required: bool) -> String {loop {print!("{}", prompt);let mut input = String::new();io::stdin().read_line(&mut input).expect("读取输入失败,请检查输入设备");let input = input.trim().to_string();// 必填项校验if required && input.is_empty() {eprintln!("⚠️ 此项为必填,请重新输入!");continue;}return input;}}/// 查询单词(支持精确/模糊匹配、按标签筛选)fn search_word(words: &[Word], target: &str, tag_filter: Option<&str>) {let target = target.to_lowercase();println!("\n🔍 单词查询(关键词:{},标签筛选:{})",
target, tag_filter.unwrap_or("无"));println!("{}", "-".repeat(40));// 筛选逻辑:关键词匹配 + 标签筛选(可选)let results: Vec<&Word> = words
.iter().filter(|w| {// 关键词匹配(英文忽略大小写)let english_match = w.english.to_lowercase().contains(&target);let chinese_match = w.chinese.to_lowercase().contains(&target);// 标签筛选(如果指定了标签)let tag_match = tag_filter.map_or(true, |tag| {
w.tags.iter().any(|t| t.to_lowercase().contains(&tag.to_lowercase()))});(english_match || chinese_match) && tag_match
}).collect();if results.is_empty() {println!("❌ 未找到符合条件的单词");return;}// 输出查询结果println!("✅ 找到 {} 个匹配单词:", results.len());for (i, word) in results.iter().enumerate() {println!("\n{}. {}", i + 1, word);}}/// 修改单词信息fn edit_word(words: &mut Vec<Word>, target: &str) {let target = target.to_lowercase();// 查找匹配的单词(精确匹配英文)let index = words
.iter().position(|w| w.english.to_lowercase() == target);if index.is_none() {eprintln!("❌ 未找到单词:{}", target);return;}let index = index.unwrap();let mut old_word = words[index].clone();println!("\n✏️ 修改单词:{}", old_word.english);println!("当前信息:");println!("{}", old_word);println!("{}", "-".repeat(40));// 交互式修改各字段(按回车保留原值)println!("提示:直接按回车保留当前值");let new_english = prompt_input(&format!("英文单词(当前:{}):", old_word.english), false);let new_chinese = prompt_input(&format!("中文释义(当前:{}):", old_word.chinese), false);let new_phonetic = prompt_input(&format!("音标(当前:{}):", old_word.phonetic), false);let new_tags_input = prompt_input(&format!("标签(当前:{}):", old_word.tags.join("、")),false,);// 更新字段(空输入则保留原值)if !new_english.is_empty() {// 检查新英文单词是否已存在if words.iter().any(|w| w.english.eq_ignore_ascii_case(&new_english) && w.english != old_word.english) {eprintln!("❌ 错误:新单词「{}」已存在", new_english);return;}
old_word.english = new_english;}if !new_chinese.is_empty() {
old_word.chinese = new_chinese;}if !new_phonetic.is_empty() {
old_word.phonetic = new_phonetic;}if !new_tags_input.is_empty() {
old_word.tags = new_tags_input
.split(',').map(|t| t.trim().to_string()).filter(|t| !t.is_empty()).collect();}// 更新单词列表并保存
words[index] = old_word.clone();save_words(words);println!("\n✅ 单词修改成功!");println!("{}", old_word);}/// 删除单词fn delete_word(words: &mut Vec<Word>, target: &str) {let target = target.to_lowercase();// 查找匹配的单词索引let index = words
.iter().position(|w| w.english.to_lowercase() == target);if index.is_none() {eprintln!("❌ 未找到单词:{}", target);return;}let index = index.unwrap();let deleted_word = words.remove(index);save_words(words);println!("✅ 成功删除单词:{}", deleted_word.english);}
分类与排序模块
支持按标签筛选单词、按多种规则排序,方便用户管理单词库:
/// 按标签筛选单词fn filter_words_by_tag(words: &[Word], tag: &str) {let tag = tag.to_lowercase();let filtered: Vec<&Word> = words
.iter().filter(|w| w.tags.iter().any(|t| t.to_lowercase().contains(&tag))).collect();if filtered.is_empty() {println!("❌ 未找到标签包含「{}」的单词", tag);return;}println!("\n🏷️ 标签筛选结果(标签:{},共 {} 个单词)", tag, filtered.len());println!("{}", "-".repeat(40));for (i, word) in filtered.iter().enumerate() {println!("\n{}. {}", i + 1, word);}}/// 单词排序(支持多种排序规则)fn sort_words(words: &mut Vec<Word>, sort_by: &str) {match sort_by.to_lowercase().as_str() {"english" | "en" => {// 按英文单词字母序排序(忽略大小写)
words.sort_by(|a, b| a.english.to_lowercase().cmp(&b.english.to_lowercase()));println!("✅ 已按英文单词字母序排序");}"time" | "date" => {// 按添加时间排序(最新添加在前)
words.sort_by(|a, b| b.add_time.cmp(&a.add_time));println!("✅ 已按添加时间排序(最新在前)");}"review" => {// 按复习次数排序(复习次数多在前)
words.sort_by(|a, b| b.review_count.cmp(&a.review_count));println!("✅ 已按复习次数排序(次数多在前)");}"accuracy" => {// 按正确率排序(正确率高在前)
words.sort_by(|a, b| {let acc_a = if a.review_count == 0 { 0.0 } else { a.correct_count as f64 / a.review_count as f64 };let acc_b = if b.review_count == 0 { 0.0 } else { b.correct_count as f64 / b.review_count as f64 };
acc_b.partial_cmp(&acc_a).unwrap_or(std::cmp::Ordering::Equal)});println!("✅ 已按测试正确率排序(正确率高在前)");}
_ => {eprintln!("❌ 不支持的排序规则:{},支持的规则:english/en、time/date、review、accuracy", sort_by);}}// 保存排序后的结果save_words(words);}
复习测试模块
实现随机抽查、中文默写两种复习模式,帮助用户巩固单词记忆:
use std::collections::HashMap;use rand::Rng; // 注:此处实际使用标准库,以下为简化实现(真实代码见完整版本)/// 随机抽查复习(英文→中文)fn review_random(words: &mut Vec<Word>, count: usize) {if words.is_empty() {eprintln!("❌ 单词本为空,无法进行复习");return;}// 限制最大抽查数量let review_count = count.min(words.len()).max(1);println!("\n📝 随机抽查复习(共 {} 题)", review_count);println!("{}", "-".repeat(40));// 随机选择单词(避免重复)let mut rng = rand::thread_rng();let mut selected_indices: Vec<usize> = (0..words.len()).collect();
rng.shuffle(&mut selected_indices);
selected_indices.truncate(review_count);let mut correct = 0;for (i, &index) in selected_indices.iter().enumerate() {let word = &mut words[index];println!("\n第 {} 题:", i + 1);println!("英文:{} {}", word.english, if word.phonetic.is_empty() { "" } else { &word.phonetic });let user_answer = prompt_input("请输入中文释义:", true);// 简单校验(包含关键词即视为正确)let is_correct = word.chinese.to_lowercase().contains(&user_answer.to_lowercase());if is_correct {
correct += 1;
word.correct_count += 1;println!("✅ 正确!标准答案:{}", word.chinese);} else {println!("❌ 错误!标准答案:{}", word.chinese);}// 更新复习次数
word.review_count += 1;}// 保存复习记录save_words(words);println!("\n{}", "-".repeat(40));println!("📊 复习完成!正确率:{}/{}({:.1}%)", correct, review_count, (correct as f64 / review_count as f64) * 100.0);}/// 中文默写模式(中文→英文)fn dictation_chinese(words: &mut Vec<Word>, count: usize) {if words.is_empty() {eprintln!("❌ 单词本为空,无法进行默写");return;}let dictation_count = count.min(words.len()).max(1);println!("\n✍️ 中文默写模式(共 {} 题)", dictation_count);println!("{}", "-".repeat(40));let mut rng = rand::thread_rng();let mut selected_indices: Vec<usize> = (0..words.len()).collect();
rng.shuffle(&mut selected_indices);
selected_indices.truncate(dictation_count);let mut correct = 0;for (i, &index) in selected_indices.iter().enumerate() {let word = &mut words[index];println!("\n第 {} 题:", i + 1);println!("中文:{}", word.chinese);let user_answer = prompt_input("请输入英文单词:", true);// 精确校验(忽略大小写)let is_correct = word.english.eq_ignore_ascii_case(&user_answer);if is_correct {
correct += 1;
word.correct_count += 1;println!("✅ 正确!英文单词:{}", word.english);} else {println!("❌ 错误!英文单词:{}", word.english);}
word.review_count += 1;}save_words(words);println!("\n{}", "-".repeat(40));println!("📊 默写完成!正确率:{}/{}({:.1}%)", correct, dictation_count, (correct as f64 / dictation_count as f64) * 100.0);}
批量操作与数据管理模块
支持批量删除、清空单词本、数据统计等高级功能:
/// 批量删除单词(按标签筛选)fn batch_delete_by_tag(words: &mut Vec<Word>, tag: &str) {let tag = tag.to_lowercase();let initial_count = words.len();// 保留不包含目标标签的单词(即删除包含目标标签的单词)
words.retain(|w| !w.tags.iter().any(|t| t.to_lowercase().contains(&tag)));let deleted_count = initial_count - words.len();if deleted_count == 0 {println!("❌ 未找到标签包含「{}」的单词,无需删除", tag);return;}// 二次确认let confirm = prompt_input(&format!("⚠️ 确认删除 {} 个包含标签「{}」的单词?(输入 yes 确认):", deleted_count, tag), true);if confirm.to_lowercase() != "yes" {println!("✅ 已取消删除操作");return;}save_words(words);println!("✅ 批量删除完成!共删除 {} 个单词", deleted_count);}/// 清空单词本(危险操作,需二次确认)fn clear_words(words: &mut Vec<Word>) {if words.is_empty() {println!("❌ 单词本已为空,无需清空");return;}println!("⚠️ 警告:此操作将删除所有单词,且无法恢复!");let confirm = prompt_input("请输入「DELETE」确认清空:", true);if confirm != "DELETE" {println!("✅ 已取消清空操作");return;}
words.clear();save_words(words);println!("✅ 单词本已清空");}/// 单词本数据统计fn stats_words(words: &[Word]) {if words.is_empty() {println!("📊 单词本统计:空");return;}// 总单词数let total = words.len();// 标签统计let mut tag_stats: HashMap<String, usize> = HashMap::new();for word in words {for tag in &word.tags {*tag_stats.entry(tag.clone()).or_insert(0) += 1;}}// 平均复习次数let avg_review: f64 = words.iter().map(|w| w.review_count as f64).sum::<f64>() / total as f64;// 整体正确率let total_review: u32 = words.iter().map(|w| w.review_count).sum();let total_correct: u32 = words.iter().map(|w| w.correct_count).sum();let overall_accuracy = if total_review == 0 { 0.0 } else { (total_correct as f64 / total_review as f64) * 100.0 };println!("\n📊 单词本数据统计");println!("{}", "-".repeat(40));println!("总单词数:{}", total);println!("标签数量:{} 个", tag_stats.len());println!("平均复习次数:{:.1} 次/词", avg_review);println!("整体测试正确率:{:.1}%", overall_accuracy);if !tag_stats.is_empty() {println!("\n标签分布:");for (tag, count) in tag_stats {println!(" {}:{} 个单词", tag, count);}}}
五、命令行交互与入口函数
设计友好的命令行交互界面,支持通过子命令调用所有功能,同时提供详细的帮助信息:
fn main() {// 加载本地单词数据let mut words = load_words();// 解析命令行参数let args: Vec<String> = std::env::args().collect();if args.len() < 2 {print_help();return;}// 处理命令match args[1].as_str() {// 基础操作命令"add" => add_word(&mut words),"search" => {if args.len() < 3 {eprintln!("❌ 用法错误:cargo run -- search <关键词> [--tag <标签>]");return;}let target = &args[2];let tag_filter = args.iter().position(|s| s == "--tag").map(|i| args.get(i + 1).unwrap().as_str());search_word(&words, target, tag_filter);}"edit" => {if args.len() < 3 {eprintln!("❌ 用法错误:cargo run -- edit <英文单词>");return;}let target = &args[2];edit_word(&mut words, target);}"delete" => {if args.len() < 3 {eprintln!("❌ 用法错误:cargo run -- delete <英文单词>");return;}let target = &args[2];delete_word(&mut words, target);}// 分类与排序命令"filter" => {if args.len() < 3 {eprintln!("❌ 用法错误:cargo run -- filter <标签关键词>");return;}let tag = &args[2];filter_words_by_tag(&words, tag);}"sort" => {let sort_by = if args.len() >= 3 { &args[2] } else { "english" };sort_words(&mut words, sort_by);}// 复习测试命令"review" => {let count = if args.len() >= 3 { args[2].parse().unwrap_or(5) } else { 5 };review_random(&mut words, count);}"dictation" => {let count = if args.len() >= 3 { args[2].parse().unwrap_or(5) } else { 5 };dictation_chinese(&mut words, count);}// 数据管理命令"stats" => stats_words(&words),"backup" => backup_words(&words),"restore" => {match restore_words() {Ok(restored) => println!("✅ 数据恢复成功!共恢复 {} 个单词", restored.len()),Err(e) => eprintln!("❌ 数据恢复失败:{}", e),}}"batch-delete" => {if args.len() < 3 {eprintln!("❌ 用法错误:cargo run -- batch-delete <标签关键词>");return;}let tag = &args[2];batch_delete_by_tag(&mut words, tag);}"clear" => clear_words(&mut words),// 帮助命令"help" => print_help(),// 未知命令
_ => {eprintln!("❌ 未知命令:{}", args[1]);print_help();}}}/// 打印帮助信息fn print_help() {println!("\n📖 本地多功能单词本 - 使用指南");println!("{}", "=".repeat(60));println!("核心功能:零依赖、本地存储、支持增删查改、分类标签、复习测试");println!("{}", "=".repeat(60));println!("\n【基础操作】");println!("cargo run -- add → 添加新单词(交互式)");println!("cargo run -- search <关键词> [--tag <标签>] → 查询单词(支持中英文模糊匹配)");println!("cargo run -- edit <英文单词> → 修改单词信息");println!("cargo run -- delete <英文单词> → 删除单词");println!("\n【分类与排序】");println!("cargo run -- filter <标签关键词> → 按标签筛选单词");println!("cargo run -- sort [规则] → 排序单词(规则:english/en、time/date、review、accuracy,默认 english)");println!("\n【复习测试】");println!("cargo run -- review [题数] → 随机抽查复习(默认 5 题,英文→中文)");println!("cargo run -- dictation [题数] → 中文默写模式(默认 5 题,中文→英文)");println!("\n【数据管理】");println!("cargo run -- stats → 查看单词本统计信息");println!("cargo run -- backup → 备份数据到 vocab_backup.txt");println!("cargo run -- restore → 从备份文件恢复数据");println!("cargo run -- batch-delete <标签> → 批量删除指定标签的单词");println!("cargo run -- clear → 清空单词本(危险操作)");println!("\n【其他】");println!("cargo run -- help → 显示此帮助信息");println!("{}", "=".repeat(60));}
六、使用指南与示例
基础操作示例
示例 1:添加单词
cargo run -- add
执行后按提示输入:
📥 添加新单词
----------------------------------------
请输入英文单词(必填):
computer
请输入中文释义(必填):
电脑;计算机
✅ 单词添加成功!
----------------------------------------



示例 2:查询单词
# 模糊查询包含 "comp" 的单词
cargo run -- search comp

🔍 单词查询(关键词:comp)
----------------------------------------
✅ 找到 1 个匹配单词:
1. 英文:computer /kəmˈpjuːtə(r)/
中文:电脑;计算机
示例 3:复习测试
# 随机抽查 3 个单词
cargo run -- review 3
📝 随机抽查复习(共 3 题)
----------------------------------------
第 1 题:
英文:computer /kəmˈpjuːtə(r)/
请输入中文释义:
电脑
✅ 正确!标准答案:电脑;计算机
第 2 题:
英文:apple /ˈæpl/
请输入中文释义:
香蕉
❌ 错误!标准答案:苹果;苹果树
第 3 题:
英文:phone /fəʊn/
请输入中文释义:
手机
✅ 正确!标准答案:手机;电话
----------------------------------------
📊 复习完成!正确率:2/3(66.7%)
数据管理示例
示例 1:查看统计信息
cargo run -- stats
📊 单词本数据统计
----------------------------------------
总单词数:3
标签数量:3 个
平均复习次数:1.0 次/词
整体测试正确率:66.7%
标签分布:
CET-4:2 个单词
科技:1 个单词
日常:2 个单词
七、项目扩展与优化方向
功能扩展
- 支持单词例句存储与显示,增强学习效果;
- 添加单词导出功能(支持 TXT/CSV 格式);
- 实现按遗忘曲线智能推荐复习单词;
- 支持自定义数据存储路径,方便多设备同步;
- 添加深色模式、自定义提示语等个性化配置。
性能优化
- 对于超大单词库(万级以上),实现分页加载与查询,提升响应速度;
- 优化文件写入逻辑,采用追加写入而非覆盖,减少 IO 开销;
- 实现单词缓存机制,避免重复解析文件。
用户体验优化
- 添加命令行补全功能,提升操作效率;
- 支持配置文件保存常用参数(如默认复习题数、排序规则);
- 增加更详细的错误提示与修复建议;
- 实现单词输入自动去重、格式校验(如音标格式)。
八、总结
本项目是一款「零依赖、多功能、轻量级」的本地单词本工具,基于 Rust 标准库开发,兼顾实用性与学习价值:
- 功能全面:覆盖单词增删查改、分类管理、复习测试、数据备份等核心需求;
- 技术亮点:充分运用 Rust 标准库特性(文件操作、字符串处理、数据结构、错误处理),无第三方依赖,跨平台兼容;
- 学习价值:适合 Rust 初学者巩固「结构体设计、文件 IO、命令行交互、迭代器与闭包」等核心知识点;
- 实用价值:数据本地存储安全可控,无网络依赖,适合语言学习者日常积累与复习。
通过本项目的开发,不仅能掌握 Rust 实战开发技巧,还能获得一款真正有用的工具,做到「学以致用」。后续可根据自身需求扩展功能,逐步提升 Rust 编程能力。
想了解更多关于Rust语言的知识及应用,可前往华为开放原子旋武开源社区(https://xuanwu.openatom.cn/)