Rust 1.83.0 版本釋出

banq發表於2024-11-29


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 };
<font>// error: constant accesses mutable global memory<i>

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

這些限制確保了常量仍然是 "常量":

  • 在整個程式執行過程中,常量的求值及其作為模式的含義(可能涉及取消引用)都是相同的。

也就是說,允許常量求值為指向可變或內部可變靜態的原始指標:

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;
<font>// error[E0764]: mutable references are not allowed in the final value of constants<i>

該版本還發布了一大批在常量上下文中穩定執行的新函式(參見 "穩定的 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語言建立者大概有限制強迫症:常量本身是一種不可變含義,限制加上這些多條條框框,好像是模糊了這個常識,主要是兩個概念關係:

  • 常量是一種不可變
  • 靜態是一種不可變

那麼:常量 + 靜態 = ?

相關文章