You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何扁平化Rust代码中的嵌套if let与if语句?

问题描述

我正在对字符串进行「归一化(normalizing)」处理,随后用它来搜索文件名的归一化版本:

use glob::glob;

fn main() {
    let text = "Hello:world-    This   is  a  test   string._,\"";
    let normalized = normalize(text);
    let pattern = "/home/alex/Downloads/papers/*";
    for entry in glob(pattern).expect("Failed to read glob pattern") {
        if let Ok(path) = entry {
            if let Some(file_name) = path.file_name().and_then(|name| name.to_str()) {
                let file_name_normalized = normalize(file_name);
                if file_name_normalized.contains(&normalized) {
                    println!("{:?}", path);
                }
            }
        }
    }
}

fn normalize(text: &str) -> String {
    let normalized = text
        .replace(&[':', ':', '-', '—', '_', ',', '.', '"'][..], "")
        .to_lowercase()
        .split_whitespace()
        .collect::<Vec<&str>>()
        .join(" ");
    normalized
}

输出结果:

"/home/alex/Downloads/papers/Hello:world-    This   is  a  test   string._,".pdf"

该代码可正常运行,但我想知道是否可以将所有嵌套的if let语句和if语句进行扁平化处理?


解决方案

可以利用Rust的迭代器适配器和?运算符,将嵌套的判断逻辑扁平化,让代码更简洁线性。优化后的代码如下:

use glob::glob;

fn main() {
    let text = "Hello:world-    This   is  a  test   string._,\"";
    let normalized = normalize(text);
    let pattern = "/home/alex/Downloads/papers/*";

    glob(pattern)
        .expect("Failed to read glob pattern")
        .filter_map(|entry| entry.ok())
        .filter_map(|path| path.file_name()?.to_str().map(|name| (path, name)))
        .filter(|(_, file_name)| normalize(file_name).contains(&normalized))
        .for_each(|(path, _)| println!("{:?}", path));
}

fn normalize(text: &str) -> String {
    text.replace(&[':', ':', '-', '—', '_', ',', '.', '"'][..], "")
        .to_lowercase()
        .split_whitespace()
        .collect::<Vec<&str>>()
        .join(" ")
}

优化说明:

  • filter_map(|entry| entry.ok()):替代外层if let Ok(path) = entry,直接过滤掉glob返回的错误条目,只保留成功的路径。
  • filter_map处理文件名提取:把path.file_name().and_then(|name| name.to_str())的逻辑整合到filter_map中,用?处理Option链式调用,失败则跳过当前条目;同时通过map绑定路径与文件名,方便后续使用。
  • filter判断匹配条件:将最后一层if判断转为filter适配器,只保留符合匹配规则的条目。
  • for_each执行打印:替代原循环体的打印逻辑,让整个流程通过迭代器链式调用完成,完全消除嵌套结构。

这种写法保持了可读性,同时符合Rust的惯用风格,把分支逻辑转化为线性的迭代器操作。

内容的提问来源于stack exchange,提问作者wyc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:07:44