Rust 团队很高兴地宣布 Rust 的新版本 1.64.0。Rust 是一门赋予每个人构建可靠且高效软件能力的编程语言。
如果你之前通过 rustup 安装了 Rust,可以使用以下命令获取 1.64.0:
$ rustup update stable
如果你尚未安装,可以从我们的网站上相应的页面获取 rustup,并在 GitHub 上查看 1.64.0 的详细发布说明。
如果你想通过测试未来版本来帮助我们,可以考虑本地更新使用 beta 通道(rustup default beta)或 nightly 通道(rustup default nightly)。请报告你可能遇到的任何 bug!
1.64.0 stable 版本有什么新内容
使用 IntoFuture 增强 .await
Rust 1.64 稳定了 IntoFuture trait。IntoFuture 是一个类似于 IntoIterator 的 trait,但 IntoIterator 用于支持 for ... in ... 循环,而 IntoFuture 改变了 .await 的工作方式。使用 IntoFuture,.await 关键字不仅可以 await futures;它还可以 await 任何可以通过 IntoFuture 转换为 Future 的东西——这有助于使你的 API 更用户友好!
例如,一个通过网络向存储提供商构建请求的 builder:
:
;
典型用法可能如下所示:
let response = new // 1. create a new instance
.set_debug // 2. set some option
.send // 3. construct the future
.await?; // 4. run the future + propagate errors
这已经不错了,但我们可以做得更好。使用 IntoFuture,我们可以将“构建 future”(第 3 行)和“运行 future”(第 4 行)合并为一个步骤:
let response = new // 1. create a new instance
.set_debug // 2. set some option
.await?; // 3. construct + run the future + propagate errors
我们可以通过为 StorageRequest 实现 IntoFuture 来做到这一点。IntoFuture 要求我们有一个可以返回的命名 future,我们可以通过创建一个“boxed future”并为其定义一个类型别名来实现:
// First we must import some new types into the scope.
use Pin;
use ;
;
// The new implementations:
// 1. create a new named future type
// 2. implement `IntoFuture` for `StorageRequest`
pub type StorageRequestFuture =
这需要更多的代码来实现,但为用户提供了更简单的 API。
未来,Rust Async 工作组希望通过支持 type 别名中的 impl Trait(Type Alias Impl Trait 或 TAIT)来简化创建新的命名 futures。这应该通过简化类型别名的签名来使实现 IntoFuture 更容易,并通过从类型别名中移除 Box 来使其性能更高。
core 和 alloc 中的 C 兼容 FFI 类型
当调用或被 C ABI 调用时,Rust 代码可以使用诸如 c_uint 或 c_ulong 之类的类型别名来匹配任何目标上 C 中的相应类型,而无需目标特定代码或条件编译。
以前,这些类型别名只在 std 中可用,因此为嵌入式目标和其他只能使用 core 或 alloc 的场景编写的代码无法使用这些类型。
Rust 1.64 现在在 core::ffi 中提供了所有 c_* 类型别名,以及用于处理 C 字符串的 core::ffi::CStr。Rust 1.64 还提供了 alloc::ffi::CString,仅使用 alloc crate 而非完整的 std 库来处理拥有所有权的 C 字符串。
rust-analyzer 现在可以通过 rustup 获取
rust-analyzer 现在已作为 Rust 附带的工具集合的一部分包含在内。这使得下载和访问 rust-analyzer 更容易,并且使其在更多平台上可用。它作为 rustup 组件提供,可以通过以下命令安装:
rustup component add rust-analyzer
目前,要运行 rustup 安装的版本,你需要这样调用它:
rustup run stable rust-analyzer
rustup 的下一个版本将提供内置代理,这样运行可执行文件 rust-analyzer 就会启动相应的版本。
大多数用户应继续使用 rust-analyzer 团队提供的版本(可在 rust-analyzer 发布页面获取),这些版本发布更频繁。使用 官方 VSCode 扩展的用户不受影响,因为它会在后台自动下载和更新版本。
Cargo 改进:工作区继承和多目标构建
在一个 Cargo 工作区中处理一组相关的库或二进制 crate 时,你现在可以避免 crate 之间通用字段值(如通用版本号、仓库 URL 或 rust-version)的重复。这也有助于在更新时使这些值在 crate 之间保持同步。更多详情请参阅 workspace.package、workspace.dependencies 以及 “从工作区继承依赖”。
当为多个目标构建时,你现在可以向 cargo build 传递多个 --target 选项,一次性构建所有这些目标。你也可以在 .cargo/config.toml 中将 build.target 设置为一个包含多个目标的数组,以便默认情况下为多个目标构建。
稳定化的 API
以下方法和 trait 实现现已稳定化:
future::IntoFuturenum::NonZero*::checked_mulnum::NonZero*::checked_pownum::NonZero*::saturating_mulnum::NonZero*::saturating_pownum::NonZeroI*::absnum::NonZeroI*::checked_absnum::NonZeroI*::overflowing_absnum::NonZeroI*::saturating_absnum::NonZeroI*::unsigned_absnum::NonZeroI*::wrapping_absnum::NonZeroU*::checked_addnum::NonZeroU*::checked_next_power_of_twonum::NonZeroU*::saturating_addos::unix::process::CommandExt::process_groupos::windows::fs::FileTypeExt::is_symlink_diros::windows::fs::FileTypeExt::is_symlink_file
这些类型以前在 std::ffi 中是稳定的,但现在在 core 和 alloc 中也可用:
core::ffi::CStrcore::ffi::FromBytesWithNulErroralloc::ffi::CStringalloc::ffi::FromVecWithNulErroralloc::ffi::IntoStringErroralloc::ffi::NulError
这些类型以前在 std::os::raw 中是稳定的,但现在在 core::ffi 和 std::ffi 中也可用:
ffi::c_charffi::c_doubleffi::c_floatffi::c_intffi::c_longffi::c_longlongffi::c_scharffi::c_shortffi::c_ucharffi::c_uintffi::c_ulongffi::c_ulonglongffi::c_ushort
我们稳定了一些与 Poll(futures 底层的低级实现)一起使用的辅助工具:
未来,我们希望提供更简单的 API,减少对 Poll 和 Pin 等低级细节的使用,但与此同时,这些辅助工具使编写此类代码变得更容易。
这些 API 现在可在 const 上下文中使用:
兼容性说明
-
如先前宣布,
linux目标现在至少需要 Linux 内核 3.2(已要求更新内核的目标除外),linux-gnu目标现在需要 glibc 2.17(已要求更新 glibc 的目标除外)。 -
Rust 1.64.0 改变了
Ipv4Addr、Ipv6Addr、SocketAddrV4和SocketAddrV6的内存布局,使其更紧凑和内存高效。这种内部表示从未暴露,但有些 crate 仍然通过使用std::mem::transmute依赖于它,导致无效的内存访问。标准库的此类内部实现细节绝不被视为稳定接口。为了限制损害,我们与所有仍在维护的这样做(依赖内部实现)的 crate 作者合作发布了修复版本,这些版本已发布一年多。绝大多数受影响的用户应该能够通过cargo update来解决。 -
作为 RLS 弃用的一部分,这也是包含 RLS 副本的最后一个版本。从 Rust 1.65.0 开始,RLS 将被一个显示弃用警告的小型 LSP 服务器取代。
其他变更
Rust 1.64 版本还有其他变更,包括:
-
Rust 编译器的 Windows 构建现在使用 profile-guided optimization (PGO,配置文件引导优化),将 Windows 上编译 Rust 代码的性能提高了 10-20%。
-
如果你定义了一个包含从未使用的字段的 struct,rustc 会警告这些未使用的字段。现在,在 Rust 1.64 中,你可以启用
unused_tuple_struct_fieldslint,以获得关于 tuple struct 中未使用字段的相同警告。在未来版本中,我们计划默认启用此 lint。类型为 unit (()) 的字段不会产生此警告,以便更容易迁移现有代码而无需更改 tuple 索引。
查看 Rust、Cargo 和 Clippy 中的所有变更。
1.64.0 的贡献者
许多人共同努力创建了 Rust 1.64.0。没有你们大家,我们无法做到这一点。感谢!