外观
第 7 节:实用小库集锦
有些库小到"一行功能",却在真实项目里天天见。这一节四个高频小库,各有各的绝活。
glob:按通配符找文件 ⭐
绝活:"src/*.rs"、"data/**/*.log" 这种"带星星的路径",一口气找出所有匹配的文件。
bash
cargo add globrust
for entry in glob::glob("src/*.rs").expect("glob 模式错误") {
match entry {
Ok(path) => println!("找到:{}", path.display()),
Err(error) => eprintln!("读取失败:{}", error),
}
}
// 找到:src\main.rs*匹配一段,**匹配多层(data/**/*.log找遍所有子目录)- 每个
entry都是Result:有的路径可能读不了(权限/已删除),逐个处理 - 比手写"递归
read_dir+ 拼路径"省一百行(内置 API 篇第 8 节的自动版)
tempfile:用完即焚的临时文件 ⭐
绝活:要一个临时文件,程序退出自动删除——不用记着清理。
bash
cargo add tempfilerust
let mut temp = tempfile::NamedTempFile::new().expect("创建临时文件失败");
std::io::Write::write_all(&mut temp, "临时数据".as_bytes()).expect("写入失败");
println!("临时文件在:{}", temp.path().display());
// 程序结束,自动删除真实场景:处理大文件时先落临时盘、下载分片暂存、测试里的临时配置——临时文件在真实项目里比想象的常见。
OnceLock:一次性初始化的全局 ⭐
绝活:"全局变量,用到才算,只算一次"——读取配置文件、建立连接池,都是它的主场。
rust
use std::sync::OnceLock;
static CONFIG: OnceLock<String> = OnceLock::new();
let config = CONFIG.get_or_init(|| {
println!("(第一次才执行)读配置文件……");
String::from("配置文件内容")
});
println!("配置:{}", config); // 第一次:读文件
println!("再取:{}", CONFIG.get().unwrap()); // 之后:直接拿get_or_init(闭包):第一次调用执行闭包并存入,以后永远直接取- 线程安全:多线程同时第一次访问,闭包也只执行一次(第 15 章
Arc<Mutex>的"全局懒加载"版) - 比
lazy_static/once_cell更新:标准库自带(1.70+),不用加依赖
dirs:用户的常用目录 ✨
绝活:"配置目录在哪、下载目录在哪"——跨平台的正确答案。
bash
cargo add dirsrust
if let Some(config_dir) = dirs::config_dir() {
// Windows: C:\Users\你\AppData\Roaming
// Linux: /home/你/.config
println!("配置目录:{}", config_dir.display());
}真实项目铁律:别往程序旁边写配置——跨平台会炸(权限、清理)。dirs::config_dir()/data_dir()/home_dir() 是标准答案。
什么时候"自己写"?
小库虽小,也要克制:能用一个库解决就别自己拼(自己拼的 ** 递归遍历,绝对没有 glob 稳)。但只为一个函数引库,也可以先手写——依赖也是成本(第 8 节细讲)。
常见误用与坑
- glob 模式写错:
**和*混用(应该data/**/*.log而不是data/*/*.log递归不到深层) - tempfile 的临时文件在哪:系统临时目录(
/tmp或%TEMP%)——别假设它在当前目录 - OnceLock 存大对象:全局会活到程序结束,别往里塞大缓存(内存不释放);"可能要清空"的全局用
Mutex<Option<T>> - dirs 返回
Option:某些平台/环境拿不到目录,if let处理