Rust 团队很高兴发布 Rust 的新版本 1.85.0。此版本同时稳定了 2024 版。Rust 是一种赋能每个人构建可靠且高效软件的编程语言。
如果您通过 rustup 安装了 Rust 的先前版本,您可以通过以下命令获取 1.85.0
$ rustup update stable
如果您还没有安装,您可以从我们网站的相应页面获取 rustup,并查看 1.85.0 的详细发布说明。
如果您想通过测试未来版本来帮助我们,您可以考虑将本地更新到使用 beta 通道 (rustup default beta) 或 nightly 通道 (rustup default nightly)。请报告您可能遇到的任何错误!
1.85.0 稳定版有什么?
Rust 2024
我们很高兴地宣布 Rust 2024 版现在已经稳定!版本是一种选择性加入的机制,用于引入可能带来向后兼容风险的更改。有关如何实现此目的的详细信息以及迁移说明,请参阅版本指南。
这是我们发布的最大的版本。 版本指南包含每个更改的详细信息,但作为总结,以下是所有更改
- 语言
- RPIT 生命周期捕获规则 — 当
use<..>不存在时,更改impl Trait类型对参数的默认捕获方式。 if let临时作用域 — 更改if let表达式中临时值的范围。- 尾部表达式临时作用域 — 更改块中尾部表达式的临时值的范围。
- 匹配人体工程学保留 — 禁止某些模式组合以避免混淆并允许未来改进。
- 不安全的
extern块 —extern块现在需要unsafe关键字。 - 不安全的属性 —
export_name、link_section和no_mangle属性现在必须标记为unsafe。 unsafe_op_in_unsafe_fn警告 —unsafe_op_in_unsafe_fnlint 现在默认为警告级别,要求在unsafe函数中使用显式的unsafe {}块。- 禁止引用
static mut— 对static mut项的引用现在会产生一个默认为拒绝的错误。 - 永不类型回退更改 — 更改永不类型
!的强制转换方式,并将never_type_fallback_flowing_into_unsafelint 级别更改为 "deny"。 - 宏片段说明符 —
macro_rules!宏中的expr宏片段说明符现在也匹配const和_表达式。 - 缺失的宏片段说明符 —
missing_fragment_specifierlint 现在是一个硬错误,拒绝没有片段说明符类型的宏元变量。 gen关键字 — 保留gen关键字,以期将来添加生成器块。- 保留语法 — 保留
#"foo"#样式的字符串和##token,以期将来更改带防护字符串字面量的解析方式。
- RPIT 生命周期捕获规则 — 当
- 标准库
- 对 prelude 的更改 — 将
Future和IntoFuture添加到 prelude 中。 - 为
Box<[T]>添加IntoIterator— 更改迭代器与装箱切片一起工作的方式。 - 新标记为不安全的函数 —
std::env::set_var、std::env::remove_var和std::os::unix::process::CommandExt::before_exec现在是不安全的函数。
- 对 prelude 的更改 — 将
- Cargo
- Cargo:感知 Rust 版本的解析器 — 更改默认的依赖解析器行为,使其考虑
rust-version字段。 - Cargo:表和键名一致性 — 移除一些过时的
Cargo.toml键。 - Cargo:拒绝未使用的继承 default-features — 更改
default-features = false在继承的工作空间依赖项中的工作方式。
- Cargo:感知 Rust 版本的解析器 — 更改默认的依赖解析器行为,使其考虑
- Rustdoc
- Rustdoc 组合测试 — Doctest 现在被组合成一个单独的可执行文件,显著提高了性能。
- Rustdoc 嵌套
include!更改 — 更改嵌套include!文件的相对路径行为。
- Rustfmt
- Rustfmt:样式版 — 引入了“样式版”概念,允许您独立于 Rust 版本控制格式化版本。
- Rustfmt:格式化修复 — 修复了许多不同情况下的格式问题。
- Rustfmt:原始标识符排序 — 更改
r#foo标识符的排序方式。 - Rustfmt:版本排序 — 更改包含整数的标识符的排序方式。
迁移到 2024 版
指南包含所有新功能的迁移说明,以及将现有项目过渡到新版本的通用说明。在许多情况下,cargo fix 可以自动完成必要的更改。您甚至可能会发现您的代码完全不需要为 2024 版进行任何更改!
请注意,通过 cargo fix 进行的自动修复非常保守,以避免改变您的代码语义。在许多情况下,您可能希望保持代码不变并使用 Rust 2024 的新语义;例如,继续使用 expr 宏匹配器,并忽略条件语句的转换,因为您想要新的 2024 版 drop 顺序语义。cargo fix 的结果不应被视为建议,而只是一种保守的转换,它保留了原有行为。
许多人共同努力创建了这个版本。我们要感谢他们所有人的辛勤工作!
async 闭包
Rust 现在支持异步闭包,例如 async || {},它们在被调用时返回 future。这就像一个 async fn,它也可以从本地环境中捕获值,就像普通闭包和函数之间的区别一样。这还附带了标准库 prelude 中的 3 个类似 trait:AsyncFn、AsyncFnMut 和 AsyncFnOnce。
在某些情况下,您可以使用常规闭包和异步块来近似实现此功能,例如 || async {}。但是,这种内部块返回的 future 无法借用闭包捕获的值,而 async 闭包可以实现这一点。
let mut vec: = vec!;
let closure = async || ;
此外,以前也无法使用返回 Future 的 Fn trait 正确表达高阶函数签名,但现在可以使用 AsyncFn trait 来实现。
use Future;
async
async
async
因此,async 闭包为这两个问题提供了第一流的解决方案!更多详情请参阅RFC 3668 和稳定化报告。
在诊断信息中隐藏 trait 实现
新的 #[diagnostic::do_not_recommend] 属性是对编译器的提示,指示其不要将带注释的 trait 实现作为诊断消息的一部分显示。对于库作者来说,这是一种阻止编译器给出可能无益或误导性建议的方法。例如
;
error[E0277]: the trait bound `MyType: Bar` is not satisfied
--> src/main.rs:9:29
|
9 | let _object: &dyn Bar = &MyType;
| ^^^^ the trait `Foo` is not implemented for `MyType`
|
note: required for `MyType` to implement `Bar`
--> src/main.rs:4:14
|
4 | impl<T: Foo> Bar for T {}
| --- ^^^ ^
| |
| unsatisfied trait bound introduced here
= note: required for the cast from `&MyType` to `&dyn Bar`
对于某些 API,实现 Foo 并通过该 blanket 实现间接获得 Bar 可能非常有意义。对于其他 API,可能期望大多数用户直接实现 Bar,因此 Foo 的建议是一个误导。在这种情况下,添加诊断提示将更改错误消息,如下所示
error[E0277]: the trait bound `MyType: Bar` is not satisfied
--> src/main.rs:10:29
|
10 | let _object: &dyn Bar = &MyType;
| ^^^^ the trait `Bar` is not implemented for `MyType`
|
= note: required for the cast from `&MyType` to `&dyn Bar`
有关最初的动机,请参阅RFC 2397,有关更多详细信息,请参阅当前的参考。
元组的 FromIterator 和 Extend 实现
早期版本的 Rust 为 (T, U) 元组对的迭代器实现了便利 trait,使其行为类似于 Iterator::unzip,在 1.56 中实现了 Extend,在 1.79 中实现了 FromIterator。这些现在已扩展到更多元组长度,从单元素 (T,) 直到长度为 12 的元组,即 (T1, T2, .., T11, T12)。例如,您现在可以使用 collect() 一次性将结果分散到多个集合中。
use ;
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
[0, 1, 16, 81, 256, 625, 1296, 2401, 4096, 6561]
std::env::home_dir() 的更新
std::env::home_dir() 已弃用多年,因为它在某些 Windows 配置中,如果设置了 HOME 环境变量(这在 Windows 上不是正常配置),可能会产生令人惊讶的结果。出于对依赖此非标准配置的代码的兼容性考虑,我们之前避免更改其行为。考虑到此函数已弃用如此之久,我们现在将其行为更新为错误修复,并且后续版本将移除此函数的弃用标记。
稳定的 API
BuildHasherDefault::newptr::fn_addr_eqio::ErrorKind::QuotaExceededio::ErrorKind::CrossesDevices{float}::midpoint- 无符号整型的
{integer}::midpoint NonZeroU*::midpoint- 为 arity 为 1 到 12 的元组实现
std::iter::Extend - 为 arity 为 1 到 12 的元组实现
FromIterator<(A, ...)> std::task::Waker::noop
这些 API 现在在 const 上下文中是稳定的
mem::size_of_valmem::align_of_valLayout::for_valueLayout::align_toLayout::pad_to_alignLayout::extendLayout::arraystd::mem::swapstd::ptr::swapNonNull::newHashMap::with_hasherHashSet::with_hasherBuildHasherDefault::new<float>::recip<float>::to_degrees<float>::to_radians<float>::max<float>::min<float>::clamp<float>::abs<float>::signum<float>::copysignMaybeUninit::write
其他更改
查看 Rust、Cargo 和 Clippy 中的所有更改。
1.85.0 的贡献者
许多人共同努力创建了 Rust 1.85.0。没有大家的贡献,我们无法完成它。感谢!