Rust编程最新版本来了!1.80正式版有哪些实用更新?

最近打开 cargo --version,不少老 Rust 用户发现终端里蹦出了 rustc 1.80.0 ——没错,Rust 官方在 2024 年 7 月底悄悄发布了 1.80 正式版。这次没搞大张旗鼓的发布会,但几个小改动,真正在日常写代码时让人“嗯?这下舒服了”。

最值得点开 Cargo.toml 的变化

以前想让某个 dev-dependency 只在测试时启用、又不想它污染构建缓存?得靠 #[cfg(test)] 加一堆条件编译。现在,Cargo 支持更干净的 optional = true + features 组合。比如你用 mockall 写单元测试,可以这样写:

[dev-dependencies]
mockall = { version = "0.29", optional = true }

然后在 [[test]] 段里指定启用它,构建时就不会多载一个 crate 进生产依赖链。

std::fs 现在能“跳过权限错误”了

写脚本遍历系统目录时,遇到 /proc/1/fd/root/.ssh 这类路径常被 read_dir() 直接 panic。1.80 给 std::fs::ReadDir 加了个新方法:next_entry() 返回 Result<DirEntry, std::io::Error>,而不是以前的 Option<Result<...>>。这意味着你可以自己决定怎么处理 PermissionDenied,比如跳过并继续往下走:

let mut entries = fs::read_dir("/proc")?;
while let Some(entry) = entries.next_entry()? {
if entry.file_type()?.is_dir() {
println!("{}", entry.path().display());
}
}

宏里的字符串字面量支持行内换行

以前写带格式的测试数据宏,像 JSON 片段,得手动拼 \n 或者用 concat!,看着别扭。现在 Rust 1.80 允许在宏调用中直接写多行字符串字面量(只要不破坏语法结构):

macro_rules! assert_json {
($val:expr, $expected:literal) => {
assert_eq!(serde_json::to_string(&$val).unwrap(), $expected);
};
}

// 现在可以这么用:
assert_json!(
User { name: "张三".to_string() },
r#"{
"name": "张三"
}"#
);

还有这些“摸得到”的改进

cargo add 默认启用 --no-default-features 标志(可配),避免一不小心把一堆用不到的 feature 拉进来;
rust-analyzer 对泛型关联类型(ATP)的跳转和补全更准了,VS Code 里按 F12 不再经常“跳空”;
#[track_caller] 现在也支持 const fn,调试 const 计算错误时能看到真实调用位置。

升级方式还是老样子:rustup update。如果你用的是 nightly,顺手加一句 rustup default stable 就能切回稳定通道。不用重启 IDE,改完 Cargo.lock 重新 cargo build,新特性就生效了——Rust 的稳,是真稳在每一步。