← 中文资源

简体中文版本

Rust E0004/E0658 — match 未穷尽

通过覆盖所有变体或添加通配分支,解决 match 非穷尽错误,并理解新增枚举变体为何会破坏调用方。

阅读英文原文

症状

遇到“Rust E0004/E0658 — match 未穷尽”时靠猜测只会浪费时间。请按证据排查:先复现症状,再执行针对性诊断,定位根因后修复,并用明确检查验证结果。

可观察到的症状包括:

  • error[E0004]: non-exhaustive patterns: Variant(_) not covered
  • match 一直正常,直到新增了枚举变体
  • 编译器提示缺少哪些分支

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

cargo build 2>&1 | sed -n "/E0004/,/^$/p"

rustc 会列出未覆盖的变体,据此精确补齐分支。

步骤 2

grep -n "^pub enum\|^enum" -A 12 src/lib.rs

查看完整枚举可确认哪些变体缺失。

常见诱因(按出现频率排序):

  • 新增了枚举变体,现有 match 未更新
  • 移除了通配分支,暴露未覆盖的变体
  • 对引用做匹配时的解构与预期不同

根因

Rust 要求 match 处理被匹配类型的所有可能值。向枚举新增变体会使原本穷尽的 match 变为非穷尽,编译器以 E0004 报告缺失的模式。

修复

为每个缺失的变体补分支;仅当默认行为确实正确时才添加有意的通配 _ =>。优先显式分支,让未来新增的变体在编译期被发现。

注意:通配分支会静默吸收新变体,削弱枚举原本提供的安全性。

enum State { Init, Running, Done }

fn label(s: &State) -> &'static str {
    match s {
        State::Init => "init",
        State::Running => "running",
        State::Done => "done",
        // no wildcard: a new variant becomes a compile error here
    }
}

验证

cargo build 通过;测试构造每个变体并断言走到预期分支。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。