发布 Rust 1.15

2017 年 2 月 2 日 · Rust 核心团队

Rust 团队很高兴宣布 Rust 的最新版本 1.15.0。Rust 是一门专注于安全性、速度和并发性的系统编程语言。

如果您已经安装了旧版本的 Rust,那么获取 Rust 1.15 非常简单,只需运行:

$ rustup update stable

如果您尚未安装 Rust,可以从我们网站的相应页面获取 rustup,并在 GitHub 上查阅 1.15.0 的详细发布说明。此版本共合入了 1443 个补丁。

1.15.0 稳定版中的特性

Rust 1.15 在稳定版中带来了备受期待的特性:custom derive(自定义派生)!回顾一下,在 Rust 中,您一直可以通过 derive 属性自动实现某些 trait:

#[derive(Debug)]
struct Pet {
    name: String,
}

然后为 Pet 实现了 Debug trait,大大减少了样板代码。然而,这仅适用于作为标准库一部分提供的 trait;它是不可定制的。Rust 1.15 现在支持自定义派生了。这意味着,如果您想将 Pet 转换为 JSON,只需将 Serde 添加到您的 Cargo.toml 文件中,就像这样:

[dependencies]
serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"

并在 Pet 上添加另一个 trait:

#[macro_use]
extern crate serde_derive;

extern crate serde_json;

#[derive(Serialize, Deserialize, Debug)]
struct Pet {
    name: String,
}

fn main() {
    let pet = Pet { name: String::from("Ferris") };

    let serialized = serde_json::to_string(&pet).unwrap();
    println!("serialized = {}", serialized);

    let deserialized: Pet = serde_json::from_str(&serialized).unwrap();
    println!("deserialized = {:?}", deserialized);
}

这将输出:

serialized = {"name":"Ferris"}
deserialized = Pet { name: "Ferris" }

另一个常见的用例是 Diesel。假设我们有一个 Pet 数据库。我们可以像这样获取它们:

// some extern crate and use lines elided here

#[derive(Queryable)]
struct Pet {
    name: String,
}

fn main() {
    use diesel_demo::schema::pets::dsl::*;

    let connection = establish_connection();
    let results = pets
        .limit(5)
        .load::<Pet>(&connection)
        .expect("Error loading pets");

    println!("Displaying {} pets", results.len());
    for pet in results {
        println!("{}", pet.name);
    }
}

有关完整说明,请参阅其网站

这类库非常强大,但为了人体工程学(ergonomics)依赖于 custom derive。虽然这些库之前在 Rust 稳定版上可以工作,但使用起来并不方便,以至于我们经常听到用户说“我只用 nightly 版本,因为需要 Serde 和 Diesel。” 使用 custom derive 是 nightly 版本中最广泛使用的特性之一。因此,去年七月提出了 RFC 1681 以支持此用例。该 RFC 于八月合并,经历了大量开发和测试,并于今天进入稳定版!

要了解如何编写自己的 custom derive,请参阅 《Rust 编程语言》一书的章节

虽然我们在此多次提到了“Serde 和 Diesel”,但使用 custom derive 还可以做很多其他很棒的事情:例如,请参阅derive-new。更多内容请参阅syn crate 的反向依赖项。(syn 对于编写 custom derive 很重要,更多信息请参阅上面链接的书籍章节。)Custom derive 也被称为“宏 1.1”(macros 1.1),因为它包含了支持更多 Rust 编译时能力的底层基础设施,这些能力被昵称为“宏 2.0”(macros 2.0)。预计在未来的版本中,您会听到更多关于这方面的信息。

其他改进

Rust 的构建系统已使用 Cargo 重新用 Rust 编写。它现在是默认的构建系统。这个过程很漫长,但最终取得了成果。考虑到所有 Rust 开发都在 master 分支上进行,我们自去年十二月以来一直使用它,并且运行良好。目前有一个开放的 PR 旨在彻底移除 Makefiles,预计将在 Rust 1.17 中完成。这将为 rustc 在编译器中使用来自 crates.io 的包铺平道路,就像任何其他 Rust 项目一样,这也进一步证明了 Cargo 的成熟度。

Rust 为 i686-unknown-openbsdMSP430ARMv5TE 平台新增了 Tier 3 支持

许多编译器性能改进已经完成。我们持续致力于提高编译器的速度。未来预计会有更多这方面的改进!

作为一项较小的改进,?Sized 现在可以在 where 子句中使用。换句话说,

struct Foo<T: ?Sized> {
    f: T,
}

struct Foo<T> where T: ?Sized {
    f: T,
}

现在接受第二种形式,并且与第一种形式等效。

更多内容请参阅详细发布说明

标准库稳定化

slice::sort 算法已重新编写,并且快了非常多。它是一种混合归并排序(hybrid merge sort),借鉴了 Timsort 的思想。此前,它是一个简单的归并排序(merge sort)。

如果您有一个 Vec<T>(其中 T: Copy),并且对其调用了 extend 方法,您的代码现在会快很多

说到速度提升,chars().count()chars().last()char_indices().last() 也变快了!

中文字符现在在 fmt::Debug 中可以正确显示了.

此外,还有许多函数也已稳定化:

更多内容请参阅详细发布说明

Cargo 特性

如果您的包顶层目录中有一个名为 build.rs 的文件,但没有 build = "build.rs" 注解,Cargo 现在会发出警告。这是为了将来能够推断出顶层的 build.rs 总是构建脚本,但目前出于兼容性考虑,仅作为警告。此前,所有构建脚本都需要配置,但此约定在社区中非常流行,因此我们将其纳入 Cargo 中。

在此版本中,Cargo 构建脚本不再通过 env!("OUT_DIR") 在构建时访问 OUT_DIR 环境变量。它们应该改为在运行时使用 std::env 检查该变量。之前在构建时设置该值是一个 bug,并且在交叉编译时是不正确的。请检查您的包,并更新以使用 std::env

cargo test 命令新增了对 --all 标志的支持,这在您使用工作空间(workspace)时非常有用。

我们现在在 Windows 上静态编译链接 MSVC CRT,并在 Mac OS X 上静态链接 OpenSSL

更多内容请参阅详细发布说明

1.15.0 贡献者

在发布公告的这部分,我们通常会列出贡献者列表。然而,我们最近启动了一项新倡议,“感谢!”(Thanks!),以便以更全面的方式来做这件事。此部分的一个问题是它只统计了对 rust-lang/rust 仓库的贡献;例如,对 Cargo 做贡献的人没有被感谢到。我们此前还需要手动生成此列表,这并非不可行,但运行正确的 git 命令来确定谁贡献了代码,这正是代码擅长的事情!

因此,您现在可以访问 https://thanks.rust-lang.org/ 查看更全面的贡献统计。如果您愿意,也可以使用别名 https://❤.rust-lang.org。目前,这只会显示我们在之前发布帖子中展示的内容。我们确实增加了一个额外功能,即按提交次数排序的总贡献列表。该列表位于:https://thanks.rust-lang.org/rust/all-time

我们已经完成了一些必要的后端工作,以便支持除 rust-lang/rust 之外的更多仓库,但这尚未完全完成。如果您想参与进来,请在 GitHub 上查看 thanks 项目

共有 137 位个人为 Rust 1.15 做出了贡献。感谢他们!