常量项
语法
常量项(ConstantItem) :
const( 标识符(IDENTIFIER) |_):类型(Type) (=表达式(Expression) )?;
一个 常量项(constant item) 是一个可选带名称的 常量值(constant value),它与程序中特定的内存位置不相关联。
常量本质上在使用的地方是内联的,这意味着它们在使用时会直接复制到相关的上下文中。这包括使用来自外部 crate 的常量以及非 Copy 类型。指向同一常量的引用不一定保证指向相同的内存地址。
常量声明在常量所在的模块或块的值命名空间(value namespace)中定义常量值。
常量必须显式指定类型。该类型必须具有 'static 生命周期:初始化器中的任何引用都必须具有 'static 生命周期。常量类型中的引用默认为 'static 生命周期;参见static lifetime elision(静态生命周期省略)。
如果常量值符合提升(promotion)条件,指向常量的引用将具有 '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, }; }
const 项的最终值不能包含指向任何可变内容的引用。
常量表达式只能在特征定义(trait definition)中省略。
带析构器的常量
常量可以包含析构器。析构器在值超出作用域时运行。
#![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 gets dropped at end of function, calling drop. // prints "Dropped. Held 0.". } }
未命名的常量
与关联常量(associated constant)不同,自由(free)常量可以使用下划线代替名称来表示未命名。例如
#![allow(unused)] fn main() { const _: () = { struct _SameNameTwice; }; // OK although it is the same name as above: const _: () = { struct _SameNameTwice; }; }
与下划线导入(underscore imports)一样,宏可以在同一作用域内安全地多次发出相同的未命名常量。例如,以下代码不应产生错误
#![allow(unused)] fn main() { macro_rules! m { ($item: item) => { $item $item } } m!(const _: () = ();); // This expands to: // const _: () = (); // const _: () = (); }
求值
自由(Free)常量总是在编译时进行求值(evaluated)以暴露 panic。即使在未使用的函数中也会发生这种情况
#![allow(unused)] fn main() { // Compile-time panic const PANIC: () = std::unimplemented!(); fn unused_generic_function<T>() { // A failing compile-time assertion const _: () = assert!(usize::BITS == 0); } }