发布 Rust 1.61.0

2022 年 5 月 19 日 · Rust 发布团队

Rust 团队很高兴宣布发布新版本 Rust 1.61.0。Rust 是一门赋予每个人构建可靠且高效软件能力的编程语言。

如果您之前通过 rustup 安装了 Rust,可以通过以下命令获取 1.61.0:

$ rustup update stable

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

如果您想通过测试未来版本来帮助我们,可以考虑在本地更新以使用 beta 通道 (rustup default beta) 或 nightly 通道 (rustup default nightly)。如果您遇到任何错误,请报告

1.61.0 稳定版有什么新内容

main 返回自定义退出码

起初,Rust 的 main 函数只能返回单元类型 ()(隐式或显式),总是表示退出状态成功;如果想表示其他状态,则必须调用 process::exit(code)。从 Rust 1.26 开始,main 函数被允许返回 Result,其中 Ok 对应 C 的 EXIT_SUCCESS,而 Err 对应 EXIT_FAILURE(同时也会调试打印错误信息)。在底层,这些备用的返回类型通过一个不稳定的 Termination trait 进行统一。

在此版本中,`Termination` trait 最终稳定了,同时稳定化的还有一个更通用的 `ExitCode` 类型,它封装了平台特定的返回类型。`ExitCode` 包含 `SUCCESS` 和 `FAILURE` 常量,并且也实现了 `From<u8>` trait 以支持任意值。您还可以为自己的类型实现 `Termination` trait,从而在转换为 `ExitCode` 之前自定义任何类型的报告。

例如,以下是一种类型安全的方式,用于为 git bisect run 脚本编写退出码:

use std::process::{ExitCode, Termination};

#[repr(u8)]
pub enum GitBisectResult {
    Good = 0,
    Bad = 1,
    Skip = 125,
    Abort = 255,
}

impl Termination for GitBisectResult {
    fn report(self) -> ExitCode {
        // Maybe print a message here
        ExitCode::from(self as u8)
    }
}

fn main() -> GitBisectResult {
    std::panic::catch_unwind(|| {
        todo!("test the commit")
    }).unwrap_or(GitBisectResult::Abort)
}

const fn 更多功能

在此版本中,一些增量功能已稳定,以实现在 const 函数中更多的功能:

  • 函数指针 (fn pointers) 的基本处理:您现在可以在 const fn 中创建、传递和转换函数指针。例如,这对于为解释器构建编译时函数表非常有用。但是,仍然不允许调用函数指针。

  • Trait bounds:您现在可以在 const fn 的泛型参数上编写 trait bounds,例如 T: Copy,而之前只允许 Sized

  • dyn Trait 类型:类似地,const fn 现在可以处理 trait 对象,即 dyn Trait

  • impl Trait 类型const fn 的参数和返回值现在可以是 opaque impl Trait 类型。

注意,这些 trait 相关的功能尚不支持在 const fn 中调用这些 trait 的方法。

请参阅参考书的常量求值章节,了解有关 const 上下文当前功能的更多信息,并可以在 rust#57563 中跟踪未来的功能。

锁定的标准 I/O 的静态句柄

三个标准 I/O 流——`Stdin`、`Stdout` 和 `Stderr`——各自都有一个 `lock(&self)` 方法,以便更好地控制读写同步。然而,它们返回的锁守卫 (lock guards) 的生命周期是从 `&self` 借用的,因此它们被限制在原始句柄的作用域内。由于底层锁实际上存储在静态内存中,这被确定为一个不必要的限制,所以现在返回的守卫具有 `'static` 生命周期,与句柄脱钩。

例如,一个常见的错误源于尝试在一个语句中获取句柄并锁定它:

// error[E0716]: temporary value dropped while borrowed
let out = std::io::stdout().lock();
//        ^^^^^^^^^^^^^^^^^       - temporary value is freed at the end of this statement
//        |
//        creates a temporary which is freed while still in use

现在锁守卫是 `'static` 的,不再从那个临时变量借用,所以这样可行了!

稳定化的 API

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

以下之前已稳定的函数现在是 const 函数:

其他更改

Rust 1.61.0 版本还有其他更改。请查看 RustCargoClippy 的更改内容。

在未来的版本中,我们计划将 Linux 内核的基线要求提高到版本 3.2,并将 glibc 提高到版本 2.17。我们非常欢迎您在 rust#95026 中提供反馈意见。

1.61.0 贡献者

许多人共同努力创建了 Rust 1.61.0。没有大家的贡献,这是不可能的。感谢!