Rust 1.83.0 版本发布


Rust 1.83.0 带来了多项改进,主要是扩展了新的常量const能力。

以下是这个版本的主要更新内容:

新的 const 能力:

  • 扩展了在常量const 上下文中运行的代码能力,包括对 const 和 static 项的初始值、数组长度、枚举区分值、常量泛型参数以及从这些上下文中可调用的函数(const fn)。
  • 允许在常量上下文中引用 static 项,但不允许读取可变或内部可变 static 的值。
  • 允许在常量上下文中使用可变引用。

静态项引用
迄今为止,除了静态项的初始化表达式之外,常量上下文都禁止引用静态static项。 现在这一限制已被取消

static S: i32 = 25;
const C: &i32 = &S;

但请注意,在常量上下文中

  • 仍然不允许读取可变或内部可变静态static值。
  • 此外,常量的最终值不得引用任何可变或内部可变静态static:
static mut S: i32 = 0;

const C1: i32 = unsafe { S };
// error: constant accesses mutable global memory

const C2: &i32 = unsafe { &S };
// error: encountered reference to mutable memory in <code>const</code>

这些限制确保了常量仍然是 "常量":

  • 在整个程序执行过程中,常量的求值及其作为模式的含义(可能涉及取消引用)都是相同的。

也就是说,允许常量求值为指向可变或内部可变静态的原始指针:

static mut S: i32 = 64;
const C: *mut i32 = &raw mut S;

可变引用和指针
现在可以在常量上下文中使用可变引用:

const fn inc(x: &mut i32) {
    *x += 1;
}

const C: i32 = {
    let mut c = 41;
    inc(&mut c);
    c
};

还支持可变原始指针和内部可变性:

use std::cell::UnsafeCell;

const C: i32 = {
    let c = UnsafeCell::new(41);
    unsafe { *c.get() += 1 };
    c.into_inner()
};

不过,可变引用和指针只能在常量的计算过程中使用,不能成为常量最终值的一部分:

const C: &mut i32 = &mut 4;
// error[E0764]: mutable references are not allowed in the final value of constants

该版本还发布了一大批在常量上下文中稳定运行的新函数(参见 "稳定的 API "部分末尾)。

这些新功能和稳定的 API 释放了在常量上下文中执行的全新代码类别,我们很高兴看到 Rust 生态系统将如何利用这一点!

稳定的 API:

  • 包括 BufRead::skip_until、ControlFlow 相关函数、DebugList、DebugMap、DebugSet、DebugTuple 的 finish_non_exhaustive 方法、ErrorKind 枚举的新变体、Option 和 Result 的新方法等。
  • 在常量上下文中稳定的 API 还包括 Cell::into_inner、Duration 相关方法、MaybeUninit 和 NonNull 的方法、OnceCell::into_inner、Option 和 Result 的方法、UnsafeCell 的方法等。

网友:
Rust语言创建者大概有限制强迫症:常量本身是一种不可变含义,限制加上这些多条条框框,好像是模糊了这个常识,主要是两个概念关系:

  • 常量是一种不可变
  • 静态是一种不可变
那么:常量 + 静态 = ?