09-常量项

常量项 — The Rust Reference

译文 · 基于 The Rust Reference

原文链接: https://doc.rust-lang.org/reference/items/constant-items.html

r[items.const]

常量项

r[items.const.syntax]

ConstantItem ->
    `const` ( IDENTIFIER | `_` ) `:` Type ( `=` Expression )? `;`

r[items.const.intro] 常量项是一个可选具名的*常量值*,它不与程序中的特定内存位置关联。

r[items.const.behavior] 常量本质上会在使用处内联,意味着使用时会直接复制到相关上下文中。这包括使用来自外部 crate 的常量,以及非 Copy 类型。对同一常量的引用不一定保证指向同一内存地址。

r[items.const.namespace] 常量声明在其所在模块或块的值命名空间中定义常量值。

r[items.const.static] 常量必须显式标注类型。该类型必须具有 'static 生命周期:初始化器中的任何引用都必须具有 'static 生命周期。常量类型中的引用默认具有 'static 生命周期;参见静态生命周期省略。

r[items.const.static-temporary] 若常量值有资格进行提升,则对该常量的引用将具有 'static 生命周期;否则会创建一个临时值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const BIT1: u32 = 1 << 0;
const BIT2: u32 = 1 << 1;

const BITS: [u32; 2] = [BIT1, BIT2];
const STRING: &'static str = "bitstring";

struct BitsNStrings<'a> {
    mybits: [u32; 2],
    mystring: &'a str,
}

const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
    mybits: BITS,
    mystring: STRING,
};

r[items.const.expr-omission] 常量表达式只能在 trait 定义中省略。

r[items.const.destructor]

带析构器的常量

常量可以包含析构器。值离开作用域时会运行析构器。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
struct TypeWithDestructor(i32);

impl Drop for TypeWithDestructor {
    fn drop(&mut self) {
        println!("Dropped. Held {}.", self.0);
    }
}

const ZERO_WITH_DESTRUCTOR: TypeWithDestructor = TypeWithDestructor(0);

fn create_and_drop_zero_with_destructor() {
    let x = ZERO_WITH_DESTRUCTOR;
    // x 在函数末尾被析构,从而调用 drop。
    // 打印 "Dropped. Held 0."。
}

r[items.const.unnamed]

未命名常量

r[items.const.unnamed.intro] 与关联常量不同,自由常量可以使用下划线代替名称从而保持未命名。例如:

1
2
3
4
const _: () =  { struct _SameNameTwice; };

// 可以,尽管与上面使用了相同的名称:
const _: () =  { struct _SameNameTwice; };

r[items.const.unnamed.repetition] 与下划线导入一样,宏可以在同一作用域中安全地多次发出相同的未命名常量。例如,下列代码不应产生错误:

1
2
3
4
5
6
7
8
macro_rules! m {
    ($item: item) => { $item $item }
}

m!(const _: () = (););
// 这会展开为:
// const _: () = ();
// const _: () = ();

r[items.const.eval]

求值

自由常量总是在编译期求值,以便暴露 panic。即使位于未使用的函数中也会发生:

1
2
3
4
5
6
7
// 编译期 panic
const PANIC: () = std::unimplemented!();

fn unused_generic_function<T>() {
    // 失败的编译期断言
    const _: () = assert!(usize::BITS == 0);
}
最后修改 August 21, 2026: 更新 (76fc81a2e)