发布 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 guards 中 by-move 绑定的共享引用,以及函数参数上的属性。此外,请查看 详细发布说明 以获取更多信息。

.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 / .await 发布的更多信息,请阅读 Niko Matsakis 的博文

match guards 中 by-move 绑定的引用

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

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

  • 按值绑定——当绑定变量的类型实现了 Copy 时为 by-copy,否则为 by-move

此前,Rust 禁止在 match 表达式的 if guards 中获取 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. 应用于项的 procedural macro 属性使用的辅助属性。

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

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

在 1.36.0 版本中,我们宣布 NLL 已经来到 Rust 2015,此前它已在 1.31 版本中首次发布用于 Rust 2018。

正如 1.36.0 版本中提到的,旧的借用检查器存在一些允许内存不安全性的 bug。这些 bug 已被 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 的发布。没有你们所有人,这一切都不可能实现。谢谢!