Rust 团队很高兴宣布 Rust 的新版本 1.36.0。Rust 是一种编程语言,它使每个人都能构建可靠且高效的软件。
如果您通过 rustup 安装了以前版本的 Rust,获取 Rust 1.36.0 就像
$ rustup update stable
如果您还没有,您可以从我们网站上的相应页面获取 rustup
,并查看 GitHub 上1.36.0 的详细发布说明。
1.36.0 稳定版中的内容
此版本带来了许多更改,包括 Future
特性、alloc
箱、MaybeUninit<T>
类型、Rust 2015 的 NLL、新的 HashMap<K, V>
实现以及 Cargo 中的 --offline
支持。继续阅读以了解一些亮点,或查看详细的发布说明以获取更多信息。
Future
来了!
在 Rust 1.36.0 中,期待已久的 Future
特性已稳定!
通过这种稳定,我们希望为重要的箱、库和生态系统提供时间来为 async
/ .await
做准备,我们将在将来告诉您更多关于它们的信息。
alloc
箱已稳定
在 1.36.0 之前,标准库由 std
、core
和 proc_macro
箱组成。core
箱提供了核心功能,例如 Iterator
和 Copy
,并且可以在 #![no_std]
环境中使用,因为它没有施加任何要求。同时,std
箱提供了 Box<T>
和操作系统功能等类型,但需要一个全局分配器和其他操作系统功能作为回报。
从 Rust 1.36.0 开始,std
中依赖于全局分配器的部分(例如 Vec<T>
)现在可以在 alloc
箱中使用。然后,std
箱重新导出这些部分。虽然使用 alloc
的 #![no_std]
二进制文件仍然需要 nightly Rust,但 #![no_std]
库箱可以在稳定的 Rust 中使用 alloc
箱。同时,没有 #![no_std]
的普通二进制文件可以依赖于此类库箱。我们希望这将有助于在稳定支持使用 alloc
的 #![no_std]
二进制文件之前,促进 #![no_std]
兼容的库生态系统的开发。
如果您是仅依赖于某些分配原语才能正常工作的库的维护者,请考虑通过在您的 lib.rs
文件顶部使用以下内容使您的库与 #[no_std]
兼容
#![no_std]
extern crate alloc;
use alloc::vec::Vec;
MaybeUninit<T>
而不是 mem::uninitialized
在以前版本的 Rust 中,mem::uninitialized
函数允许您通过假装已初始化类型为 T
的值而无需执行任何操作来绕过 Rust 的初始化检查。此函数的主要用途之一是延迟分配数组。
但是,mem::uninitialized
是一个极其危险的操作,实际上无法正确使用,因为 Rust 编译器假设值已正确初始化。例如,调用 mem::uninitialized::<bool>()
会导致立即未定义的行为,因为从 Rust 的角度来看,未初始化的位既不是 0
(对于 false
)也不是 1
(对于 true
) - bool
允许的唯一两种位模式。
为了解决这种情况,在 Rust 1.36.0 中,类型 MaybeUninit<T>
已稳定。Rust 编译器将了解它不应该假设 MaybeUninit<T>
是一个已正确初始化的 T
。因此,您可以更安全地进行逐步初始化,并在确定 maybe_t: MaybeUninit<T>
包含已初始化的 T
后最终使用 .assume_init()
。
由于 MaybeUninit<T>
是更安全的替代方案,因此从 Rust 1.39 开始,函数 mem::uninitialized
将被弃用。
要详细了解未初始化的内存、mem::uninitialized
和 MaybeUninit<T>
,请阅读Alexis Beingessner 的博客文章。标准库还包含有关 MaybeUninit<T>
的大量文档。
Rust 2015 的 NLL
在 Rust 1.31.0 的公告中,我们告诉您有关 NLL(非词法生命周期)的信息,这是对语言的改进,它使借用检查器更智能、更易于使用。例如,您现在可以编写
fn main() {
let mut x = 5;
let y = &x;
let z = &mut x; // This was not allowed before 1.31.0.
}
在 1.31.0 中,NLL 仅针对 Rust 2018 稳定,并承诺我们也会将其移植到 Rust 2015。随着 Rust 1.36.0 的发布,我们很高兴地宣布我们已经做到了!NLL 现在可用于 Rust 2015。
随着两个版本都支持 NLL,我们离移除旧的借用检查器更近了一步。但是,旧的借用检查器不幸地接受了一些它不应该接受的不安全代码。因此,NLL 目前处于“迁移模式”,如果 NLL 借用检查器拒绝旧的 AST 借用检查器会接受的代码,我们将发出警告而不是错误。请查看此列表,其中列出了受影响的公共箱。
要详细了解 NLL、MIR、修复健全性漏洞的故事以及如果遇到警告可以采取的措施,请阅读Felix Klock 的博客文章。
HashMap<K, V>
实现
新的 在 Rust 1.36.0 中,HashMap<K, V>
实现已被替换为 hashbrown
箱中的实现,该实现基于SwissTable 设计。虽然接口相同,但 HashMap<K, V>
实现现在平均速度更快,并且内存开销更低。请注意,与 hashbrown
箱不同,std
中的实现仍然默认为 SipHash 1-3 哈希算法。
--offline
支持
Cargo 中的 在大多数构建过程中,Cargo 不会与网络交互。但是,有时 Cargo 必须这样做。例如,当添加依赖项时,需要下载最新的兼容版本。但是,有时网络访问不可用,例如在飞机上或隔离的构建环境中。
在 Rust 1.36 中,一个新的 Cargo 标志已稳定:--offline
。该标志会更改 Cargo 的依赖项解析算法,使其仅使用本地缓存的依赖项。当所需的箱在脱机状态下不可用时,并且需要网络访问,Cargo 将退出并显示错误。要预先填充本地缓存以准备脱机使用,请使用 cargo fetch
命令,该命令会下载项目所需的所有依赖项。
要详细了解 --offline
和 cargo fetch
,请阅读Nick Cameron 的博客文章。
有关 Cargo 其他更改的信息,请查看详细的发布说明。
库更改
dbg!
宏现在支持多个参数。
此外,一些 API 已变为 const
新的 API 已稳定,包括
task::Waker
和task::Poll
VecDeque::rotate_left
和VecDeque::rotate_right
Read::read_vectored
和Write::write_vectored
Iterator::copied
BorrowMut<str> for String
str::as_mut_ptr
其他库变更可在 详细发布说明 中找到。
其他变更
详细的 1.36.0 版本发布说明可用于 Rust、Cargo 和 Clippy。
1.36.0 贡献者
许多人共同创建了 Rust 1.36.0。没有你们,我们无法做到。 感谢!