编程时生成“非必要”文件或目录是很常见的,可以安全地删除这些文件或目录,而不会导致数据丢失或对系统造成损害。此类文件/目录的示例是捕获 macOS 上目录状态的
.DS_Store
文件夹,或在 python3 编译期间创建的 __pycache__
文件夹,或 .bash_history
文件——所有这些及其同类文件都可以安全地删除或“.gitignored” '.
在学习 Rust 时,我第一次尝试使用 Rust 脚本来清理此类“碎屑”,如下例所示。
虽然这有效,但我不确定这是惯用的铁锈。特别是,
entry.file_name().to_str().map(|s| s.starts_with(pattern)).unwrap_or(false)
看起来相当冗长。
在Python中,
# entry is a pathlib.Path
if entry.name.starts_with(pattern):
这种冗长的“展开”是生锈不可避免的一个方面吗?经验丰富的 Rust 程序员会如何编写这样的函数?
#![allow(unused)]
use std::fs;
use walkdir::WalkDir;
fn remove(entry: walkdir::DirEntry) {
let p = entry.path();
println!("Deleting {}", p.display());
if entry.metadata().unwrap().is_file() {
fs::remove_file(p);
} else {
fs::remove_dir_all(p);
}
}
fn main() -> std::io::Result<()> {
let startswith_patterns = vec![
// directory
".DS_Store",
"__pycache__",
".mypy_cache/",
".ruff_cache",
".pylint_cache",
// file
".bash_history",
".python_history",
"pip-log.txt",
];
let endswith_patterns = vec![
// directory
".egg-info",
".coverage",
// file
".pyc",
".log",
];
let mut counter = 0;
for entry in WalkDir::new(".").into_iter().filter_map(|e| e.ok()) {
for pattern in &startswith_patterns {
if entry.file_name().to_str().map(|s| s.starts_with(pattern)).unwrap_or(false) {
counter += 1;
remove(entry.clone());
}
}
for pattern in &endswith_patterns {
if entry.file_name().to_str().map(|s| s.ends_with(pattern)).unwrap_or(false) {
counter += 1;
remove(entry.clone());
}
}
}
println!("Deleted {} items of detritus", counter);
Ok(())
}