如何在Rust中按模式递归搜索文件并正确过滤结果?
Rust walkdir 模式匹配过滤问题解决
一、修复is_hidden函数的返回值错误
你原代码里的核心问题是map闭包里的for循环是语句,没有返回值(实际返回()),但map需要返回bool类型,导致编译器报错。用any方法可以直接实现“是否匹配任意忽略模式”的逻辑:
use walkdir::{DirEntry, WalkDir}; fn is_hidden(entry: &DirEntry) -> bool { let ignores = [".tmp", ".exe"]; entry.file_name() .to_str() // 用iter()遍历数组,any()判断是否存在匹配项 .map(|s| ignores.iter().any(|i| s.ends_with(i))) .unwrap_or(false) } fn main() { let mut it = WalkDir::new("foo").into_iter(); loop { let entry = match it.next() { None => break, Some(Err(err)) => panic!("ERROR: {}", err), Some(Ok(entry)) => entry, }; if is_hidden(&entry) { if entry.file_type().is_dir() { it.skip_current_dir(); } continue; } println!("{}", entry.path().display()); } }
关键修正:
- 替换
for循环为ignores.iter().any(...),any会遍历数组并返回是否有任意一个条件成立 - 用
iter()遍历数组,避免所有权转移导致的潜在问题
二、修复finder函数的过滤逻辑
你的finder当前是保留匹配忽略后缀的文件,而从需求来看应该是排除这些文件,同时代码缺少必要的导入,修正后如下:
use std::path::{Path, PathBuf}; use std::error::Error; use walkdir::WalkDir; fn finder(path: &Path) -> Result<Vec<PathBuf>, Box<dyn Error>> { let ignores = [".exe", ".psd", ".mp4"]; let matching_files: Vec<PathBuf> = WalkDir::new(path) .into_iter() .filter_map(|e| e.ok()) // 用!取反,排除匹配忽略模式的文件 .filter(|e| e.file_name().to_str().map_or( false, |s| !ignores.iter().any(|i| s.ends_with(i)) )) .map(|x| x.path().to_owned()) .collect(); Ok(matching_files) }
关键修正:
- 补充
std::path和std::error的导入,解决Path、Error未定义的问题 - 在
any前加!反转过滤逻辑,实现排除指定后缀文件的需求 - 替换
ignores.into_iter()为ignores.iter(),避免闭包多次调用时的所有权问题
内容的提问来源于stack exchange,提问作者little ghost
相关产品推荐
相关产品推荐

