靜態和常數

Static and constant variables are two different ways to create globally-scoped values that cannot be moved or reallocated during the execution of the program.

const

常數變數會在編譯期間評估,且無論用於何處,其值都會內嵌:

const DIGEST_SIZE: usize = 3;
const ZERO: Option<u8> = Some(42);

fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] {
    let mut digest = [ZERO.unwrap_or(0); DIGEST_SIZE];
    for (idx, &b) in text.as_bytes().iter().enumerate() {
        digest[idx % DIGEST_SIZE] = digest[idx % DIGEST_SIZE].wrapping_add(b);
    }
    digest
}

fn main() {
    let digest = compute_digest("Hello");
    println!("digest: {digest:?}");
}

根據《Rust RFC 手冊》所述,這類值會在使用時內嵌。

您只能在編譯期間呼叫標示為 const 的函式,以便產生 const 值,但可以在執行階段呼叫 const 函式。

static

靜態變數會在程式的整個執行過程中持續運作,因此不會移動:

static BANNER: &str = "Welcome to RustOS 3.14";

fn main() {
    println!("{BANNER}");
}

As noted in the Rust RFC Book, these are not inlined upon use and have an actual associated memory location. This is useful for unsafe and embedded code, and the variable lives through the entirety of the program execution. When a globally-scoped value does not have a reason to need object identity, const is generally preferred.

This slide should take about 5 minutes.
  • 別忘了提到 const 的行為在語意上與 C++ 的 constexpr 相似。
  • 另一方面,static 則更類似於 C++ 中的 const 或可變動的全域變數。
  • static 提供物件識別子,也就是記憶體中的位址,和具有內部可變動性型別 (例如 Mutex<T>) 所需的狀態。
  • 需要在執行階段評估常數的情況雖不常見,但這會比使用靜態項目更有用且安全。

屬性表:

資源靜態常數
具備記憶體中的位址否 (已內嵌)
在整個程式執行期間持續存在
可變動是 (不安全)
Evaluated at compile time是 (已在編譯時初始化)
無論在何處使用都會內嵌

探索更多內容

Because static variables are accessible from any thread, they must be Sync. Interior mutability is possible through a Mutex, atomic or similar.

Thread-local data can be created with the macro std::thread_local.