Rust 团队很高兴地宣布 Rust 的新版本 1.70.0。Rust 是一种编程语言,旨在赋予每个人构建可靠和高效软件的能力。
如果您之前通过 rustup 安装了 Rust,您可以使用以下命令获取 1.70.0:
$ rustup update stable
如果您尚未安装,您可以从我们网站上的相应页面获取 rustup
,并查看 GitHub 上 1.70.0 的详细发行说明。
如果您想通过测试未来的版本来帮助我们,您可以考虑在本地更新以使用 beta 频道 (rustup default beta
) 或 nightly 频道 (rustup default nightly
)。请报告您可能遇到的任何错误!
1.70.0 稳定版的新特性
crates.io 默认使用 sparse 协议
Cargo 的 “sparse” 协议现在默认启用,用于从 crates.io 读取索引。此功能之前已在 Rust 1.68.0 中稳定,但仍需要配置才能与 crates.io 一起使用。之前宣布的计划是在 1.70.0 中将其设为默认,现在它来了!
当从 crates.io 索引获取信息时,您应该会看到性能显着提高。位于限制性防火墙后的用户需要确保可以访问 https://index.crates.io
。如果出于某种原因,您需要保留之前使用 GitHub 托管的 git 索引的默认设置,则可以使用 registries.crates-io.protocol
配置设置来更改默认设置。
关于更改访问方法需要注意的一个副作用是,这也更改了 crate 缓存的路径,因此依赖项将被重新下载。一旦您完全致力于使用 sparse 协议,您可能需要清除旧的 $CARGO_HOME/registry/*/github.com-*
路径。
OnceCell
和 OnceLock
稳定了两种新类型,用于一次性初始化共享数据:OnceCell
及其线程安全的对应物 OnceLock
。这些类型可以用于任何不需要立即构造,甚至可能无法构造的情况,例如全局变量中的非 const
数据。
use std::sync::OnceLock;
static WINNER: OnceLock<&str> = OnceLock::new();
fn main() {
let winner = std::thread::scope(|s| {
s.spawn(|| WINNER.set("thread"));
std::thread::yield_now(); // give them a chance...
WINNER.get_or_init(|| "main")
});
println!("{winner} wins!");
}
诸如 lazy_static
和 once_cell
之类的 crate 过去已经满足了这种需求,但现在这些构建块已成为标准库的一部分,从 once_cell
的 unsync
和 sync
模块移植而来。未来可能还会稳定更多的方法,以及存储其初始化函数的配套 LazyCell
和 LazyLock
类型,但是稳定化的第一步应该已经涵盖了许多用例。
IsTerminal
这个新稳定的 trait 具有一个单一的方法 is_terminal
,用于确定给定的文件描述符或句柄是否代表终端或 TTY。这是标准化外部 crate 中已存在的功能的另一个例子,例如 atty
和 is-terminal
,在 Unix 目标上使用 C 库 isatty
函数,并在其他地方使用类似的功能。一个常见的用例是程序区分是在脚本中运行还是在交互模式下运行,例如在交互时呈现颜色甚至完整的 TUI。
use std::io::{stdout, IsTerminal};
fn main() {
let use_color = stdout().is_terminal();
// if so, add color codes to program output...
}
调试信息的命名级别
-Cdebuginfo
编译器选项之前仅支持数字 0..=2,用于表示递增的调试信息量,其中 Cargo 在 dev 和 test profiles 中默认为 2,在 release 和 bench profiles 中默认为 0。现在可以使用名称设置这些调试级别:“none” (0)、“limited” (1) 和 “full” (2),以及两个新级别 “line-directives-only” 和 “line-tables-only”。
Cargo 和 rustc 文档之前都将级别 1 称为 “line tables only”,但它不仅仅如此,它还包含关于所有函数的信息,只是不包含类型和变量。该级别现在称为 “limited”,而新的 “line-tables-only” 级别进一步减少到仅包含带有文件名和行号的回溯所需的最少信息。这最终可能成为 -Cdebuginfo=1
使用的级别。另一个 line-directives-only
级别旨在用于 NVPTX 分析,否则不建议使用。
请注意,这些命名选项尚不能通过 Cargo.toml
使用。对该功能的支持将在下一个版本 1.71 中提供。
test
CLI 中强制执行稳定性
在 当编译 #[test]
函数时,可执行文件会从 test
crate 获取命令行界面。此 CLI 有许多选项,包括一些尚未稳定且需要指定 -Zunstable-options
的选项,就像 Rust 工具链中的许多其他命令一样。但是,虽然这仅在 nightly 构建中允许,但该限制在 test
中并不活跃 —— 直到现在。从 1.70.0 开始,Rust 的 stable 和 beta 构建将不再允许不稳定的 test
选项,使其真正像文档中描述的那样仅限于 nightly 版本。
已知在某些情况下,不稳定的选项可能在用户不知情的情况下被使用,特别是 IntelliJ Rust 和其他 IDE 插件中使用的 --format json
。这些项目已经在调整以适应此更改,并且可以在其 跟踪 issue 中关注 JSON 输出的状态。
稳定的 API
NonZero*::MIN/MAX
BinaryHeap::retain
std::collections::binary_heap::IntoIter 的 Default 实现
std::collections::btree_map::{IntoIter, Iter, IterMut} 的 Default 实现
std::collections::btree_map::{IntoKeys, Keys} 的 Default 实现
std::collections::btree_map::{IntoValues, Values} 的 Default 实现
std::collections::btree_map::Range 的 Default 实现
std::collections::btree_set::{IntoIter, Iter} 的 Default 实现
std::collections::btree_set::Range 的 Default 实现
std::collections::linked_list::{IntoIter, Iter, IterMut} 的 Default 实现
std::vec::IntoIter 的 Default 实现
std::iter::Chain 的 Default 实现
std::iter::Cloned 的 Default 实现
std::iter::Copied 的 Default 实现
std::iter::Enumerate 的 Default 实现
std::iter::Flatten 的 Default 实现
std::iter::Fuse 的 Default 实现
std::iter::Rev 的 Default 实现
std::slice::Iter 的 Default 实现
std::slice::IterMut 的 Default 实现
Rc::into_inner
Arc::into_inner
std::cell::OnceCell
Option::is_some_and
NonNull::slice_from_raw_parts
Result::is_ok_and
Result::is_err_and
std::sync::atomic::Atomic*::as_ptr
std::io::IsTerminal
std::os::linux::net::SocketAddrExt
std::os::unix::net::UnixDatagram::bind_addr
std::os::unix::net::UnixDatagram::connect_addr
std::os::unix::net::UnixDatagram::send_to_addr
std::os::unix::net::UnixListener::bind_addr
std::path::Path::as_mut_os_str
std::sync::OnceLock
其他更改
查看 Rust、Cargo 和 Clippy 中所有更改的内容。
1.70.0 的贡献者
许多人共同努力创建了 Rust 1.70.0。没有你们所有人,我们不可能做到。谢谢!