发布 Rust 1.48.0

2020 年 11 月 19 日 · Rust 发布团队

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

如果你之前已经通过 rustup 安装了 Rust,获取 Rust 1.48.0 十分简单,只需执行以下命令:

$ rustup update stable

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

1.48.0 stable 版本包含什么

本次发布的重点是 Rustdoc,它带来了一些改进,让编写文档变得更加轻松!请参阅详细发布说明,了解本文未涵盖的其他变更。

在 rustdoc 中更方便地创建链接

Rustdoc 是 Rust 发行版中包含的库文档生成工具,它允许你使用 Markdown 编写文档。这使得使用起来非常容易,但也存在一些痛点。假设你正在为以下 Rust 代码编写文档:

pub mod foo {
    pub struct Foo;
}

pub mod bar {
    pub struct Bar;
}

我们有两个模块,每个模块中都有一个 struct。假设我们想将这两个 struct 一起使用;我们可能想在文档中对此进行说明。因此,我们会编写如下所示的文档:

pub mod foo {
    /// Some docs for `Foo`
    ///
    /// You may want to use `Foo` with `Bar`.
    pub struct Foo;
}

pub mod bar {
    /// Some docs for `Bar`
    ///
    /// You may want to use `Bar` with `Foo`.
    pub struct Bar;
}

这都很好,但如果我们能链接到这些其他 type 就更好了。这将使我们的库用户在文档中轻松地在它们之间导航。

这里的问题在于 Markdown 不了解 Rust 以及 rustdoc 生成的 URL。因此,Rust 程序员不得不手动写出这些链接:

pub mod foo {
    /// Some docs for `Foo`
    ///
    /// You may want to use `Foo` with [`Bar`].
    ///
    /// [`Bar`]: ../bar/struct.Bar.html
    pub struct Foo;
}

pub mod bar {
    /// Some docs for `Bar`
    ///
    /// You may want to use `Bar` with [`Foo`].
    ///
    /// [`Foo`]: ../foo/struct.Foo.html
    pub struct Bar;
}

请注意,我们还必须使用相对链接,以便它能离线工作。这个过程不仅繁琐且容易出错,而且在某些地方根本就是错误的。如果我们把一个 pub use bar::Bar 放在 crate 根目录,这会在根目录中重新导出 Bar。现在我们的链接就错了。但如果我们修复它们,那么当导航到模块内的 Bar 时,链接又会是错误的。你实际上无法手动编写这些链接,并确保它们全部准确无误。

在此版本中,你可以使用一些语法让 rustdoc 知道你正在尝试链接到某个 type,它将为你生成 URL。以下是基于之前代码的两个不同示例:

pub mod foo {
    /// Some docs for `Foo`
    ///
    /// You may want to use `Foo` with [`Bar`](crate::bar::Bar).
    pub struct Foo;
}

pub mod bar {
    /// Some docs for `Bar`
    ///
    /// You may want to use `Bar` with [`crate::foo::Foo`].
    pub struct Bar;
}

第一个示例将显示与之前相同的文本;但会生成指向 Bar type 的正确链接。第二个示例将链接到 Foo,但会将完整的 crate::foo::Foo 作为链接文本显示。

你可以在这里使用多种选项。请参阅 rustdoc 手册中关于“按名称链接条目”的部分了解更多信息。Inside Rust 博客上还有一篇关于此功能历史的文章,由部分贡献者撰写!

添加搜索别名

你现在可以在条目上指定 #[doc(alias = "<alias>")],以便在使用 rustdoc 的 UI 搜索时添加搜索别名。这是一个较小的改动,但仍然很有用。它看起来像这样:

#[doc(alias = "bar")]
struct Foo;

通过此注解,如果在 rustdoc 的搜索框中搜索“bar”,Foo 将会出现在结果中,即使搜索文本中没有“Foo”字样。

一个有趣的别名用例是 FFI 封装 crate,其中每个 Rust 函数都可以为其封装的 C 函数添加别名。这样,底层 C 库的现有用户就可以轻松地搜索到对应的 Rust 函数了!

标准库变更

最显著的 API 变更是:[T; N]: TryFrom<Vec<T>> 现在已稳定。这是什么意思?嗯,你可以使用它尝试将一个 vector 转换为给定长度的 array:

use std::convert::TryInto;

let v1: Vec<u32> = vec![1, 2, 3];

// This will succeed; our vector has a length of three, we're trying to
// make an array of length three.
let a1: [u32; 3] = v1.try_into().expect("wrong length");

// But if we try to do it with a vector of length five...
let v2: Vec<u32> = vec![1, 2, 3, 4, 5];

// ... this will panic, since we have the wrong length.
let a2: [u32; 3] = v2.try_into().expect("wrong length");

在上一个版本中,我们讨论了标准库能够使用 const generics。这是一个很好的示例,展示了我们可以通过这类功能添加哪些类型的 API。预计很快会听到更多关于 const generics 稳定化的消息。

此外,本次版本中还有五个新 API 被稳定:

以下之前已稳定的 API 现在已标记为 const

请参阅详细发布说明了解更多信息。

其他变更

Rust 1.48.0 版本还有其他变更:查看 RustCargoClippy 中的变更内容。

1.48.0 贡献者

许多人共同努力创造了 Rust 1.48.0。没有你们的支持,我们无法做到这一点。感谢!