Rust 1.61.0 版本发布

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

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

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

$ rustup update stable

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

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

1.61.0 稳定版的新特性

main 函数的自定义退出码

起初,Rust 的 main 函数只能返回 unit 类型 ()(隐式或显式),总是表示退出状态成功。如果需要其他退出状态,您必须调用 process::exit(code)。自 Rust 1.26 起,main 允许返回 Result,其中 Ok 转换为 C 的 EXIT_SUCCESSErr 转换为 EXIT_FAILURE(同时也会调试打印错误)。在底层,这些备选返回类型通过一个不稳定的 Termination trait 统一起来。

在此版本中,Termination trait 终于稳定了,同时稳定下来的还有一个更通用的 ExitCode 类型,它包装了平台特定的返回类型。ExitCode 类型具有 SUCCESSFAILURE 常量,并且还实现了 From<u8>,以支持更任意的值。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 指针的基本处理:现在您可以在 const fn 中创建、传递和转换函数指针。例如,这对于为解释器构建编译时函数表可能很有用。但是,仍然不允许调用 fn 指针。

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

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

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

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

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

锁定 stdio 的静态句柄

三个标准 I/O 流 -- StdinStdoutStderr -- 每个都有一个 lock(&self) 方法,以允许更好地控制读取和写入的同步。但是,它们返回的锁守卫的生命周期是从 &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 版本。没有你们所有人,我们不可能做到这一点。感谢!