Rust 团队很高兴宣布 Rust 的最新版本 1.17.0。Rust 是一种系统编程语言,专注于安全性、速度和并发性。
如果您已经安装了 Rust 的旧版本,获取 Rust 1.17 非常简单,只需运行
如果您还没有安装 Rust,可以从官网相应的页面获取 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 = &;
// new
const NAMES: & = &;
另一个类似的改进是“字段初始化简写”。类似于 ECMAScript 6 中称为“对象字面量属性值简写”的功能,声明结构体时可以去除重复,例如这样
// definitions
let x = 5;
let y = 6;
// old
let p = Point ;
// new
let p = Point ;
也就是说,x, y 形式将假定其值被设置为与其在作用域中同名的变量的值。
另一个小的使用体验改进是,新的 Rustacean 们经常尝试使用 + 将两个 &str 连接起来。这是行不通的,您只能连接 String + &str。因此,添加了一个新的错误信息来帮助犯此错误的用户
// code
"foo" + "bar"
// old
error: binary operation `+` cannot be applied to type `&'static str`
-:2:5
|
2 | "foo" + "bar"
| ^^^^^
|
note: an implementation of `Add` might be missing for `&'static str`
-:2:5
|
2 | "foo" + "bar"
| ^^^^^
// new
error: binary operation `+` cannot be applied to type `&'static str`
-: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.rs 文件,并编写 build = "build.rs"。此约定现已编码进 Cargo,如果 build.rs 存在,将默认使用它。我们在过去几个版本中一直在对此变化进行警告,您可以使用 build = false 来选择不使用此约定。
此版本标志着旧的基于 Makefile 的构建系统被移除了。新的系统在 Rust 1.15 中宣布,是用 Rust 编写的,主要使用 Cargo 来驱动构建。它现在已经足够成熟,可以成为唯一的构建系统了。
作为此更改的一部分,现在可以在 Rust 的构建系统中使用来自 crates.io 的包。第一个被添加的是 mdBook,它现在正被用于渲染我们各种类书的文档
- 书籍(The Book) (仓库)
- 参考手册(The Reference) (仓库)
- Nomicon (仓库)
此外,请查看这些指向它们各自仓库的链接;它们已被移出主代码树。此外,我们还添加了第四本书,仍在主代码树中:不稳定功能手册(The Unstable Book)。这本书按名称提供了不稳定功能的概述,包含指向其跟踪议题的链接,并可能包含初步文档。如果您希望某个功能稳定下来,请参与其跟踪议题!
几个版本之前,rustup 默认停止安装文档。我们做出此更改是为了节省带宽,并且不是所有用户都需要一份本地文档副本。然而,这也产生了一个陷阱:一些用户没有意识到此更改,只有在无法连接到互联网时才会注意到。此外,一些用户确实想要一份本地文档副本,无论他们是否联网。因此,我们撤销了此更改,现在文档又默认安装了。
最后,虽然此版本充满了改进,但有一个小小的退步我们不得不遗憾地通知您。在 Windows 上,Visual Studio 2017 已经发布,并且 Microsoft 改变了软件的安装结构。Rust 无法自动检测到此位置,虽然我们正在进行必要的更改,但未能及时赶上此版本。在此之前,Visual Studio 2015 仍然工作正常,或者您可以在命令行上运行 vcvars.bat。我们希望很快能使其无缝工作。
有关更多信息,请参阅详细发行说明。
标准库功能稳定
此版本中稳定了 19 个新的 API
Arc::into_raw和Rc::into_raw允许您消耗一个Arc或Rc并获得一个原始指针。Arc::from_raw和Rc::from_raw允许您从原始指针获得一个Arc或Rc。Arc::ptr_eq和Rc::ptr_eq返回两个Arc或两个Rc是否指向同一个值(而不仅仅是比较相等的值)。Ordering::then允许您将两个Ordering链接在一起,而Ordering::then_with允许您通过函数来实现。BTreeMap::range允许您迭代BTreeMap的一部分,而BTreeMap::range_mut允许您进行可变迭代。collections::Bound可以让您有更多控制。process::abort将以异常方式彻底终止一个进程。ptr::read_unaligned和ptr::write_unaligned类似于ptr::read和ptr::write,但没有对齐要求。Result::expect_err与Result::expect相对应,用于处理Err情况而不是Ok情况。Cell::swap类似于std::mem::swap,但允许您使用&Cell而不是&mut T。Cell::replace类似于std::mem::replace,但允许您使用&Cell而不是&mut T。Cell::into_inner允许您消耗Cell并提取其值。Cell::take允许您从Cell中取出值,留下Default::default。
在其他更改中,Cell<T> 以前对其许多方法要求 T: Copy,但此要求已显著放宽。
Box<T> 现在实现了十几种新的 From 转换。
SocketAddr 和 IpAddr 也新增了一些新的转换。以前,您可能需要编写这样的代码
"127.0.0.1:3000".parse.unwrap
现在,您可以编写
from
// or even
.into
这可以去除一些不必要的运行时解析,并且根据您的偏好,可读性大致相同。
堆栈回溯(Backtraces)现在有了更好的格式,默认省略了一些信息。例如,完整的堆栈回溯以前是这样
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 来获取完整的堆栈回溯。未来我们可能会做更多清理;有关更多信息,请参阅此 bug。
有关更多信息,请参阅详细发行说明。
Cargo 新功能
除了之前提到的 build.rs 更改外,Cargo 还有一些新的改进。cargo check --all 和 cargo run --package 是两个之前缺失但现在支持的参数。
您现在可以选择忽略 SSL 证书吊销检查。当然,默认设置仍然是检查。
Cargo.toml 中的一个新字段 required-features 允许您指定构建目标时必须启用的特定功能。例如:假设我们正在编写一个与数据库交互的 crate,并且支持多种数据库。我们的 Cargo.toml 可能像这样
[]
# ...
= []
= []
= []
tools 功能允许我们包含额外的工具,而 postgres 和 sqlite 功能控制我们想要支持哪些数据库。
以前,cargo build 会尝试构建所有目标,这通常是您想要的行为。但是,如果我们有一个 src/bin/postgres-tool.rs,它只有在启用 postgres 和 tools 功能时才真正有用,那该怎么办?以前,我们不得不写这样的代码
这是大量用于规避 cargo build 默认行为的样板代码。对于 examples/ 目录下的示例来说更是如此,这些示例应该展示如何使用您的库,但这种奇特的写法只在包内部有用,如果您自己尝试使用该示例则无效。
使用新的 required-features 键,我们可以添加这个
[[]]
# ...
= ["postgres", "tools"]
现在,只有当我们设置了这两个功能时,cargo build 才会构建我们的 postgres-tool,这样我们就可以编写一个普通的 fn main 函数,而无需那些烦人的 cfg 代码了。
有关更多信息,请参阅详细发行说明。
1.17.0 的贡献者
许多人共同努力创造了 Rust 1.17。没有你们的支持,我们不可能做到这一点。感谢!