原文

1.86.0稳定版中有什么

上转特征

此版本包括一项期待已久的功能,上转特征对象的能力.如果一个特征有一个超特征,可强制转换所述特征对象的引用超特征的特征对象的引用:

这里

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

这同样适合任何其他类型的(智能)指针,如Arc<dyn Trait> -> Arc<dyn Supertrait> *const dyn Trait -> *const dyn Supertrait

以前,这需要在特征自身使用上转方法,如fn as_supertrait(&self) -> &dyn Supertrait,这仅适合一个引用/指针.现在不再需要此类解决方法.

注意,即指向特征对象原始指针带一个重要的不变量:将指向有无效虚表特征对象原始指针"泄漏"到安全代码中可能会导致未定义行为.

当前还没有决定,在控制良好的环境中,临时创建此原始指针是否会导致立即的未定义行为,因此代码在任何条件下都应避免创建此类指针.

特征上转可能对Any特征特别有用,因为它允许,无需添加任何特征方法或使用外部,将特征对象上转到dyn Any以调用Any下转方法.

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_mutAPI文档的示例:

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]属性标记安全函数.

以前,只有不安全的函数才能使用#[target_feature]属性标记,因为在不允许目标功能调用此类函数是不合理的.

此版本稳定了target_feature_11功能,允许使用#[target_feature]属性标记安全函数.
只能从标有目标特征属性其他函数安全调用,标有目标特征属性安全函数.但是,不能把它们传递给接受Fn*特征绑定的模板的函数,并仅支持强制到标有target_feature属性的函数内的函数指针.

在未标记有目标特征属性的函数中,可在不安全块内调用它们,但是调用者负责确保目标特征可用.

#[target_feature(enable = "avx2")]
fn requires_avx2() {
    //...剪断
}
#[target_feature(enable = "avx2")]
fn safe_callsite() {
     //在此调用`"requires_avx2"`是安全的,因为`"safe_callsite"`自身需要`"avx2"`特征.
    requires_avx2();
}
fn unsafe_callsite() {
    //在此调用`"requires_avx2"`是不安全的,因为必须首先确保`"avx2"`功能可用.
    if is_x86_feature_detected!("avx2") {
        unsafe { requires_avx2() };
    }
}

你可查看target_features_11RFC了解更多信息,这里.

在需要健壮性时,调试断定指针为非空

编译器现在将在表明指针在非零大小的读写时不为空时,及当在引用中重新借用指针时,插入调试断定.如,当允许调试断定时,以下代码现在将产生不展开崩溃:

let _x = *std::ptr::null::<u8>();
let _x = &*std::ptr::null::<u8>();

Rust1.53.0以来,对此平凡示例已产生了警告,无论复杂程度如何,新的运行时检查此时将检测.

仅在允许调试断定时,才有这些断定,即不得依赖它们来保证其健壮性.这也表明,即使由允许了调试断定的代码调用也是如此,在禁止调试断定(如标准库)时,编译的依赖将不会触发断定.

默认missing_abi检查警告

块和函数(如extern{}extern fn)中省略ABI,现在将导致警告(通过missing_abi检查).在关键字后省略ABI总是隐式导致"C"ABI.
现在建议显式指定"C"ABI(如extern"C"{}extern"C"fn).
可查看显式ExternABIRFC以取更多信息,这里.

1.87.0的目标弃用警告

将在下个版本Rust1.87.0中删除,第2层的i586-pc-windows-msvc目标.它与更流行i686-pc-windows-msvc的不同在,它不需要SSE2指令支持,但窗口10(所有窗口目标(win7目标除外)的最低操作系统版本)自身需要SSE2指令.

当前以i586-pc-windows-msvc为目标的所有用户都应在1.87.0版本之前,迁移到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现在在环境中是稳定的:

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
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐