Rust 1.39.0 版本发布

2019 年 11 月 7 日 · Rust 发布团队

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

如果您之前通过 rustup 安装了 Rust 的版本,那么获取 Rust 1.39.0 版本非常简单,只需运行:

$ rustup update stable

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

1.39.0 稳定版的新特性

Rust 1.39.0 的亮点包括 async/.awaitmatch 守卫中对移动绑定(by-move bindings)的共享引用,以及函数参数上的属性。此外,请参阅详细发行说明以获取更多信息。

.await 时代结束,async fn 来了

此前在 Rust 1.36.0 版本中,我们宣布 Future trait 已经到来。当时,我们提到:

通过这次稳定化,我们希望给重要的 crate、库和生态系统时间来为 async / .await 做好准备,我们将在未来告诉您更多相关信息。

一诺千金。因此在 Rust 1.39.0 版本中,我们很高兴地宣布 async / .await 已经稳定化!具体来说,这意味着您可以定义 async 函数和代码块,并对其使用 .await

一个 async 函数,您可以通过编写 async fn 而不是 fn 来引入它,除了在被调用时返回一个 Future 之外,什么也不做。这个 Future 是一个挂起的计算,您可以通过 .await 它来驱动其完成。除了 async fn 之外,async { ... }async move { ... } 代码块(类似于闭包)可以用来定义“async 字面量”。

要了解更多关于 async / .await 发布的信息,请阅读 Niko Matsakis 的博客文章

match 守卫中对移动绑定(by-move bindings)的引用

当在 Rust 中进行模式匹配时,一个变量(也称为“绑定”)可以通过以下方式绑定:

  • 按引用绑定,可以是不可变的或可变的。这可以通过显式方式实现,例如分别通过 ref my_varref mut my_var。但在大多数情况下,绑定模式将自动推断。

  • 按值绑定 -- 要么是按复制(by-copy),当绑定变量的类型实现了 Copy 时,否则就是按移动(by-move)

以前,Rust 会禁止在 match 表达式的 if 守卫中获取对按移动(by-move)绑定的共享引用。这意味着以下代码会被拒绝:

fn main() {
    let array: Box<[u8; 4]> = Box::new([1, 2, 3, 4]);

    match array {
        nums
//      ---- `nums` is bound by move.
            if nums.iter().sum::<u8>() == 10
//                 ^------ `.iter()` implicitly takes a reference to `nums`.
        => {
            drop(nums);
//          ----------- `nums` was bound by move and so we have ownership.
        }
        _ => unreachable!(),
    }
}

在 Rust 1.39.0 中,上面的代码片段现在可以被编译器接受了。我们希望这将为 match 表达式带来更流畅和更一致的体验。

函数参数上的属性

在 Rust 1.39.0 中,现在允许在函数、闭包和函数指针的参数上使用属性。以前,您可能需要这样写:

#[cfg(windows)]
fn len(slice: &[u16]) -> usize {
    slice.len()
}
#[cfg(not(windows))] 
fn len(slice: &[u8]) -> usize {
    slice.len()
}

...现在您可以更简洁地写成:

fn len(
    #[cfg(windows)] slice: &[u16], // This parameter is used on Windows.
    #[cfg(not(windows))] slice: &[u8], // Elsewhere, this one is used.
) -> usize {
    slice.len()
}

您可以在此位置使用的属性包括:

  1. 条件编译:cfgcfg_attr

  2. 控制 lint:allowwarndenyforbid

  3. 应用于项的过程宏属性使用的辅助属性。

    我们希望这将用于在整个生态系统中提供更具可读性和人体工程学的基于宏的 DSL。

借用检查迁移警告在 Rust 2018 中成为硬错误

在 1.36.0 版本中,我们宣布 在 Rust 2018 中首次发布 NLL 后,NLL 也来到了 Rust 2015 1.31

正如在 1.36.0 版本中提到的,旧的借用检查器存在一些错误,可能会导致内存不安全。这些错误已由 NLL 借用检查器修复。由于这些修复破坏了一些稳定的代码,我们决定逐步引入错误,方法是检查旧的借用检查器是否会接受程序,而 NLL 检查器会拒绝它。如果是这样,这些错误将改为警告。

在 Rust 1.39.0 中,这些警告现在是 Rust 2018 中的错误。在下一个版本 Rust 1.40.0 中,这也将适用于 Rust 2015,这将最终允许我们 移除旧的借用检查器,并保持编译器的清洁。

如果您受到影响,或者想了解更多信息,请阅读 Niko Matsakis 的博客文章

标准库中更多的 const fn

在 Rust 1.39.0 中,以下函数变为 const fn

标准库的新增功能

在 Rust 1.39.0 中,以下函数被稳定化:

其他更改

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

另请参阅兼容性说明,以检查您是否受到这些更改的影响。

1.39.0 版本的贡献者

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