Rust 1.58.0 版本发布

2022年1月13日 · Rust 发布团队

Rust 团队很高兴地宣布 Rust 新版本 1.58.0 发布。Rust 是一种编程语言,旨在赋能所有人构建可靠且高效的软件。

如果您之前通过 rustup 安装了 Rust,那么升级到 Rust 1.58.0 非常简单,只需运行:

$ rustup update stable

如果您还没有安装 Rust,您可以从我们的网站上的相应页面获取 rustup,并查看 GitHub 上 1.58.0 版本的详细发布说明

1.58.0 稳定版的新特性

Rust 1.58 带来了格式化字符串中的捕获标识符、Windows 上 Command 搜索路径的更改、标准库中更多的 #[must_use] 注解以及一些新的库稳定化。

格式化字符串中的捕获标识符

现在,格式化字符串可以通过在字符串中简单地写入 {ident} 来捕获参数。格式化字符串长期以来接受位置参数(可选地通过索引)和命名参数,例如:

println!("Hello, {}!", get_person());                // implicit position
println!("Hello, {0}!", get_person());               // explicit index
println!("Hello, {person}!", person = get_person()); // named

现在,命名参数也可以从周围的作用域捕获,例如:

let person = get_person();
// ...
println!("Hello, {person}!"); // captures the local `person`

这也可以用于格式化参数:

let (width, precision) = get_format();
for (name, score) in get_scores() {
  println!("{name}: {score:width$.precision$}");
}

格式化字符串只能捕获纯标识符,不能捕获任意路径或表达式。对于更复杂的参数,可以先将它们赋值给局部名称,或者使用旧式的 name = expression 格式化参数。

此功能适用于所有接受格式化字符串的宏。但是,一个特殊情况是 2015 和 2018 版本的 panic! 宏,其中 panic!("{ident}") 仍然被视为未格式化的字符串 —— 编译器会警告这没有达到预期的效果。由于 2021 版本更新了 panic 宏以实现 改进的一致性,因此这在 2021 版本的 panic! 中按预期工作。

缩减 Windows Command 搜索路径

在 Windows 目标平台上,std::process::Command 将不再搜索当前目录中的可执行文件。这种效果归因于 win32 CreateProcess API 的历史行为,因此 Rust 实际上按以下顺序搜索:

  1. (Rust 特有的)子进程的 PATH 环境变量中列出的目录,如果它与父进程的显式不同。
  2. 应用程序加载的目录。
  3. 父进程的当前目录。
  4. 32 位 Windows 系统目录。
  5. 16 位 Windows 系统目录。
  6. Windows 目录。
  7. PATH 环境变量中列出的目录。

但是,使用当前目录可能会导致令人惊讶的结果,甚至在处理不受信任的目录时可能导致恶意行为。例如,ripgrep 在得知他们的子进程可能以这种方式被拦截时,发布了 CVE-2021-3013。即使是微软自己的 PowerShell 文档 也指出,出于安全考虑,他们不使用当前目录。

Rust 现在执行自己的搜索,不包含当前目录,并且也不包含遗留的 16 位目录,因为没有 API 可以发现其位置。因此,Rust 在 Windows 上的新 Command 搜索顺序是:

  1. 子进程的 PATH 环境变量中列出的目录。
  2. 应用程序加载的目录。
  3. 32 位 Windows 系统目录。
  4. Windows 目录。
  5. PATH 环境变量中列出的目录。

非 Windows 目标平台继续使用其平台特定的行为,通常只考虑子进程或父进程的 PATH 环境变量。

标准库中更多 #[must_use]

当未能显式考虑类型或函数或其输出几乎肯定是错误时,可以将 #[must_use] 属性应用于类型或函数。长期以来,这已在标准库中用于像 Result 这样的类型,应该检查其错误条件。这也有助于捕捉错误,例如期望函数就地修改值,但实际上它返回一个新值。

提案 35 于 2021 年 10 月获得批准,旨在审核和扩展 #[must_use] 在整个标准库中的应用,涵盖更多主要效果是返回值的函数。这类似于函数纯度的概念,但比真正的语言特性更宽松。其中一些添加项出现在 1.57.0 版本中,现在在 1.58.0 版本中,这项工作已经完成。

稳定的 API

以下方法和 trait 实现已稳定化。

以下先前稳定的函数现在是 const

其他更改

Rust 1.58.0 版本中还有其他更改:请查看 RustCargoClippy 中的更改。

1.58.0 版本的贡献者

许多人齐心协力创造了 Rust 1.58.0。没有你们所有人,我们不可能做到。谢谢!