Rust: 1.86.0 新版本发布。

原文链接 Rust 团队欣然宣布:Rust 1.86.0 正式发布!

Rust 是一门帮助每个人构建可靠且高效软件的编程语言。

如果你已经通过 rustup 安装了旧版 Rust,可执行:

bash 复制代码
$ rustup update stable

即可升级到 1.86.0。

如果尚未安装,请访问官网的 appropriate page on our website 获取 rustup,并查阅 [1.86.0 详细发行说明]

想帮忙测试未来版本?可以将本地工具链切换到 beta 通道(rustup default beta)或 nightly 通道(rustup default nightly)。如发现任何 Bug,欢迎反馈!

1.86.0 稳定版亮点

Trait 向上转型(Trait upcasting)

本次发布带来了期盼已久的 Trait 对象向上转型 功能。若某个 trait 拥有 supertrait ,即可将对其 trait 对象的引用自动协变为 supertrait 的 trait 对象引用:

rust 复制代码
trait Trait: Supertrait {}
trait Supertrait {}

fn upcast(x: &dyn Trait) -> &dyn Supertrait {
    x
}

同理,Arc 可转为 Arc,*const dyn Trait 可转为 *const dyn Supertrait,等等。

此前常见的变通做法是在 Trait 内添加 fn as_supertrait(&self) -> &dyn Supertrait,且只能处理一种指针类型;如今皆无需再写样板代码。

需注意:裸指针指向的 vtable 必须有效;泄露带无效 vtable 的裸指针到安全代码会触发 未定义行为。在可控语境下临时创建此类裸指针是否立即 UB,仍待进一步规范,因此应避免任何情况下创建它们(Miri 亦会检查)。

此特性对 Any trait 尤其有用:可先将自定义 trait 对象向上转型为 dyn Any,再调用 Any::downcast*,无需增添额外 trait 方法或依赖第三方 crate。

rust 复制代码
use std::any::Any;

trait MyAny: Any {}

impl dyn MyAny {
    fn downcast_ref<T>(&self) -> Option<&T> {
        (self as &dyn Any).downcast_ref()
    }
}

您可以在 Rust 参考中了解有关特征向上转型的更多信息。

HashMap 与切片支持 可变多元素索引

由于借用检查规则,重复调用 get_mut 取到的可变引用不能并存。为安全地同时借多处元素,标准库现新增 get_disjoint_mut(切片与 HashMap 均提供)。示例(节选自 slice::get_disjoint_mut: 文档):

rust 复制代码
let v = &mut [1, 2, 3];
if let Ok([a, b]) = v.get_disjoint_mut([0, 2]) {
    *a = 413;
    *b = 612;
}
assert_eq!(v, &[413, 2, 612]);

if let Ok([a, b]) = v.get_disjoint_mut([0..1, 1..3]) {
    a[0] = 8;
    b[0] = 88;
    b[1] = 888;
}
assert_eq!(v, &[8, 88, 888]);

if let Ok([a, b]) = v.get_disjoint_mut([1..=2, 0..=0]) {
    a[0] = 11;
    a[1] = 111;
    b[0] = 1;
}
assert_eq!(v, &[1, 11, 111]);

允许 安全函数 使用 #[target_feature]

此前仅 unsafe fn 可标记 #[target_feature],因为若在未启用目标指令集时调用会造成未定义行为。本次稳定 target_feature_11,允许 安全函数 标记该属性。

带 #[target_feature(...)] 的安全函数,只能在 同样标记 的函数体内安全调用。 若在未标记函数中调用,必须置于 unsafe 块并自行检测特性是否可用。

rust 复制代码
#[target_feature(enable = "avx2")]
fn requires_avx2() {
    // ... snip
}

#[target_feature(enable = "avx2")]
fn safe_callsite() {
    // Calling `requires_avx2` here is safe as `safe_callsite`
    // requires the `avx2` feature itself.
    requires_avx2();
}

fn unsafe_callsite() {
    // Calling `requires_avx2` here is unsafe, as we must
    // ensure that the `avx2` feature is available first.
    if is_x86_feature_detected!("avx2") {
        unsafe { requires_avx2() };
    }
}

您可以查看target_features_11RFC 来获取更多信息。

调试断言:指针空值检查

编译器现会在调试断言开启时,为指针解引用(非零大小读写)或重新借用为引用时插入 非空检查。例如:

rust 复制代码
let _x = *std::ptr::null::<u8>();
let _x = &*std::ptr::null::<u8>();

类似警告自 1.53.0 起已存在;如今不论代码复杂度,运行时均能捕获。 注意:仅在开启 debug_assertions 的构建中插入检查,不能依赖其保证内存安全。

missing_abi 现默认为 warn

省略 extern 块/函数的 ABI(如 extern {}、extern fn)现会触发 missing_abi 警告。推荐显式写成 extern "C" {} 或 extern "C" fn。 背景可见 Explicit Extern ABIs RFC

1.87.0 将移除目标 i586-pc-windows-msvc

Tier-2 目标 i586-pc-windows-msvc 将于 下一个版本 Rust 1.87.0 移除。区别在于该目标 不要求 SSE2,但 Windows 10(所有 windows 目标的最低支持版本,win7 系列除外)自身已依赖 SSE2。 请所有使用该目标的项目迁移至 i686-pc-windows-msvc。详见重大变更提案

稳定的 API

  • {float}::next_down

  • {float}::next_up

  • <[_]>::get_disjoint_mut

  • <[_]>::get_disjoint_unchecked_mut

  • slice::GetDisjointMutError

  • HashMap::get_disjoint_mut

  • HashMap::get_disjoint_unchecked_mut

  • NonZero::count_ones

  • Vec::pop_if

  • sync::Once::wait

  • sync::Once::wait_force

  • sync::OnceLock::wait 这些 API 现在在 const 上下文中是稳定的:

  • hint::black_box

  • io::Cursor::get_mut

  • io::Cursor::set_position

  • str::is_char_boundary

  • str::split_at

  • str::split_at_checked

  • str::split_at_mut

  • str::split_at_mut_checked 其他变化 查看Rust、Cargo和Clippy中发生的所有变化。

1.86.0 的贡献者 Rust 1.86.0 的诞生离不开众多开发者的共同努力。没有你们,我们不可能完成这一切。谢谢!

相关推荐
Pomelo_刘金4 小时前
用 DDD 把「闹钟」需求一点点捏出来
架构·rust·领域驱动设计
Pomelo_刘金4 小时前
Clean Architecture 整洁架构:借一只闹钟讲明白「整洁架构」的来龙去脉
后端·架构·rust
a cool fish(无名)14 小时前
rust-方法语法
开发语言·后端·rust
a cool fish(无名)1 天前
rust-参考与借用
java·前端·rust
叶 落1 天前
[Rust 基础课程]猜数字游戏-获取用户输入并打印
rust·rust基础
RustFS1 天前
RustFS 如何修改默认密码?
rust
景天科技苑2 天前
【Rust线程池】如何构建Rust线程池、Rayon线程池用法详细解析
开发语言·后端·rust·线程池·rayon·rust线程池·rayon线程池
该用户已不存在2 天前
Zig想要取代Go和Rust,它有资格吗
前端·后端·rust
用户1774125612443 天前
不懂装懂的AI,折了程序员的阳寿
rust
量子位3 天前
vivo自研蓝河操作系统内核开源!Rust开发新机遇来了
rust·ai编程