宣布 Rust 1.17

2017 年 4 月 27 日 · Rust 核心团队

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

如果您已安装了以前版本的 Rust,获取 Rust 1.17 非常简单

$ rustup update stable

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

1.17.0 稳定版中的新内容

Rust 1.17.0 的故事主要是关于一些小的、提高生活质量的改进。例如,'static 生命周期现在在静态和常量中被假定。当您编写这样的常量或静态时

const NAME: &'static str = "Ferris";
static NAME: &'static str = "Ferris";

Rust 1.17 将允许您省略 'static,因为这是唯一有意义的生命周期

const NAME: &str = "Ferris";
static NAME: &str = "Ferris";

在某些情况下,这可以消除大量的样板代码

// old
const NAMES: &'static [&'static str; 2] = &["Ferris", "Bors"];

// new
const NAMES: &[&str; 2] = &["Ferris", "Bors"];

另一个类似的改进是“字段初始化简写”。类似于 ECMAScript 6,它称之为“对象字面量属性值简写”,在声明结构体时可以消除重复,例如

// definitions
struct Point {
    x: i32,
    y: i32,
}

let x = 5;
let y = 6;

// old
let p = Point {
    x: x,
    y: y,
};

// new
let p = Point {
    x,
    y,
};

也就是说,x, y 形式将假设其值被设置为其作用域中具有相同名称的变量。

对于另一个小的生活质量改进,新的 Rustaceans 通常会尝试使用 + 将两个 &str 加在一起。这不起作用,您只能添加 String + &str。因此,添加了一个新的错误消息 来帮助犯此错误的用户

// code
"foo" + "bar"

// old
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^
  |
note: an implementation of `std::ops::Add` might be missing for `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^

// new
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^
  |
  = note: `+` can't be used to concatenate two `&str` strings
help: to_owned() can be used to create an owned `String` from a string
reference. String concatenation appends the string on the right to the string on
the left and may require reallocation. This requires ownership of the string on
the left.
  |     "foo".to_owned() + "bar"

在使用 Cargo 的构建脚本时,您必须在 Cargo.toml 中设置脚本的位置。但是,绝大多数人编写了 build = "build.rs",使用项目根目录中的 build.rs 文件。 此约定现在已编码到 Cargo 中,如果存在 build.rs,则将被假定。我们已经警告了这种变化几个版本,您可以使用 build = false 选择退出。

此版本标志着旧的基于 Makefile 的构建系统的移除。在 Rust 1.15 中宣布的新系统是用 Rust 编写的,主要使用 Cargo 来驱动构建。它现在已经足够成熟,可以成为唯一的构建系统。

作为该更改的一部分,crates.io 中的包现在可以在 Rust 的构建系统中使用。第一个被添加的是 mdBook,并且它现在被用来渲染我们各种类似书籍的文档

此外,请查看它们各自仓库的链接;它们已移出树。此外,我们还添加了第四本书,仍在树中:不稳定版。这提供了按名称对不稳定功能的概述,包含指向其跟踪问题的链接,并且可能包含初始文档。如果您想看到某个功能被稳定,请参与其跟踪问题!

几个版本之前,rustup 默认情况下停止安装文档。我们进行了此更改以节省一些带宽,因为并非所有用户都希望在本地拥有文档副本。但是,这造成了一个陷阱:一些用户没有意识到这种变化,并且只有在不再连接到互联网时才会注意到。此外,一些用户确实希望拥有文档的本地副本,无论其连接性如何。因此,我们恢复了更改,并且文档再次默认安装。

最后,虽然此版本充满了改进,但我们遗憾地通知您,有一个小步骤后退。在 Windows 上,Visual Studio 2017 已发布,并且 Microsoft 更改了软件安装方式的结构。 Rust 无法自动检测此位置,虽然我们正在进行必要的更改,但它们没有及时完成此版本。在那之前,Visual Studio 2015 仍然可以正常工作,或者您可以在命令行上运行 vcvars.bat。我们希望很快就能以无缝的方式完成这项工作。

查看详细的发行说明以了解更多信息。

库稳定化

此版本稳定了 19 个新的 API 部分

在其他更改中,Cell<T> 过去要求 T: Copy 才能使用其许多方法,但现在已大大放宽了此要求

Box<T> 现在实现了 使用 From 的十几个新的转换。

SocketAddrIpAddr 也有一些新的转换。以前,您可能写过这样的代码

"127.0.0.1:3000".parse().unwrap()

现在,您可以编写

SocketAddr::from(([127, 0, 0, 1], 3000))
// or even
([127, 0, 0, 1], 3000).into()

这消除了一些不必要的运行时解析,并且在可读性方面大致相同,具体取决于您的偏好。

回溯现在具有更好的格式,默认情况下省略了一些内容。例如,完整的回溯

thread 'main' panicked at 'explicit panic', foo.rs:2
stack backtrace:
   1:     0x55c39a23372c - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x55c39a23571e - std::panicking::default_hook::{{closure}}::h59672b733cc6a455
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:351
   3:     0x55c39a235324 - std::panicking::default_hook::h1670459d2f3f8843
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:367
   4:     0x55c39a235afb - std::panicking::rust_panic_with_hook::hcf0ddb069e7beee7
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:555
   5:     0x55c39a22e866 - std::panicking::begin_panic::heb433e9aa28a7408
   6:     0x55c39a22e9bf - foo::main::hd216d4a160fcce19
   7:     0x55c39a23d44a - __rust_maybe_catch_panic
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libpanic_unwind/lib.rs:98
   8:     0x55c39a236006 - std::rt::lang_start::hd7c880a37a646e81
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:436
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panic.rs:361
                        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/rt.rs:57
   9:     0x55c39a22e9e9 - main
  10:     0x7f5e5ed3382f - __libc_start_main
  11:     0x55c39a22e6b8 - _start
  12:                0x0 - <unknown>

现在改为

thread 'main' panicked at 'explicit panic', foo.rs:2
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
             at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at /checkout/src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at /checkout/src/libstd/sys_common/backtrace.rs:60
             at /checkout/src/libstd/panicking.rs:355
   3: std::panicking::default_hook
             at /checkout/src/libstd/panicking.rs:371
   4: std::panicking::rust_panic_with_hook
             at /checkout/src/libstd/panicking.rs:549
   5: std::panicking::begin_panic
   6: foo::main
   7: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
   8: std::rt::lang_start
             at /checkout/src/libstd/panicking.rs:433
             at /checkout/src/libstd/panic.rs:361
             at /checkout/src/libstd/rt.rs:57
   9: main
  10: __libc_start_main
  11: _start

默认情况下。您可以设置环境变量 RUST_BACKTRACE=full 以获取完整的回溯。我们将来可能能够进行更多清理;查看此错误以了解更多信息。

查看详细的发行说明以了解更多信息。

Cargo 功能

除了前面提到的 build.rs 更改之外,Cargo 还有一些新的改进。 cargo check --allcargo run --package 是两个现在支持的缺失标志。

您现在可以选择加入忽略 SSL 吊销检查。默认情况下仍然是检查,当然。

Cargo.toml 中的一个新字段 required-features 允许您指定必须为目标设置的特定功能。以下是一个示例:假设我们正在编写一个与数据库交互的 crate,并且我们支持多个数据库。我们可能在 Cargo.toml 中有以下内容

[features]
# ...
postgres = []
sqlite = []
tools = []

tools 功能允许我们包含额外的工具,而 postgressqlite 功能控制我们想要支持哪些数据库。

以前,cargo build 会尝试构建所有目标,这通常是您想要的。但是,如果我们有一个 src/bin/postgres-tool.rs,它实际上只在启用 postgrestools 功能时才相关?以前,我们必须编写类似这样的代码

#[cfg(not(all(feature = "postgres", feature = "tools")))]
fn main() {
    println!("This tool requires the `postgres` and `tools` features to be enabled.");
}

#[cfg(all(feature = "postgres", feature = "tools"))]
fn main() {
    // real code
}

这是为了解决 cargo build 的行为而编写的大量样板代码。对于 examples/ 来说,情况更糟糕,它应该展示如何使用您的库,但这种胡闹只在包内相关,如果您要自己尝试使用该示例,则无关紧要。

使用新的 required-features 键,我们可以添加以下内容

[[bin]]
# ...
required-features = ["postgres", "tools"]

现在,cargo build 只有在我们设置了这两个功能时才会构建我们的 postgres-tool,因此我们可以编写一个普通的 fn main,而无需所有 cfg 废话妨碍我们。

查看详细的发行说明以了解更多信息。

1.17.0 的贡献者

许多人共同努力创造了 Rust 1.17。没有你们,我们无法做到。 感谢!