常量条目
常量条目 是一个可选名称的、不与程序中特定内存位置关联的 常量值 。
常量在使用时本质上是内联的,这意味着当它们在相关上下文中使用时,会被直接拷贝。
这包括使用来自外部 crate 的常量,以及 非-Copy
类型。对同一常量的引用不能保证引用同一内存地址。
常量必须显式指定类型。该类型必须具有 'static
生命周期:初始化器中的任何引用都必须具有 'static
生命周期。
常量可以引用其他常量的地址,在这种情况下,地址将省略适用的生命周期,否则 (在大多数情况下) 默认为 static
生命周期 (请参见 静态生命周期省略 ) 。
但编译器仍然有自由将常量解释为多个值,因此引用的地址可能不稳定。
#![allow(unused)] fn main() { 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, }; }
常量表达式只能在 trait 定义 中省略。
常量析构函数
常量可以包含析构函数。当常量的值超出其作用域时,析构函数将被执行。
#![allow(unused)] fn main() { 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。 // prints "Dropped. Held 0.". } }
匿名常量
与 关联常量 不同,可以使用下划线代替名称来表示 自由 匿名常量。例如:
#![allow(unused)] fn main() { const _: () = { struct _SameNameTwice; }; // OK 虽然和上面的同名: const _: () = { struct _SameNameTwice; }; }
与 下划线导入 类似,宏可以安全地在同一作用域内多次发送相同的匿名常量。例如,以下示例不应产生错误:
#![allow(unused)] fn main() { macro_rules! m { ($item: item) => { $item $item } } m!(const _: () = ();); // 这扩展为: // const _: () = (); // const _: () = (); }
评估
自由 常量总是在编译时被 计算,以便暴露 panic。即使在未使用的函数中,也会发生这种情况:
#![allow(unused)] fn main() { // 编译时 panic const PANIC: () = std::unimplemented!(); fn unused_generic_function<T>() { // 一个失败的编译时断言 const _: () = assert!(usize::BITS == 0); } }