常量项
Syntax
ConstantItem →
const ( IDENTIFIER | _ ) : Type ( = Expression )? ;
常量项 是一个可选命名的 常量值 ,它不与程序中特定的内存位置相关联。
常量在本质上是在其被使用的地方内联的,这意味着在使用时它们被直接复制到相关的上下文中。这包括使用来自外部 crate 的常量,以及非 Copy 类型。指向同一常量的引用不一定保证指向相同的内存地址。
常量声明在其所在的模块或代码块的 值命名空间 中定义常量值。
常量必须显式指定类型。该类型必须具有 'static 生命周期:初始化程序中的任何引用都必须具有 '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,
};
}
常量表达式仅在 特型定义 中可以省略。
带有析构函数的常量
常量可以包含析构函数。当值超出作用域时,析构函数将运行。
#![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,调用 drop。
// 打印 "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 _: () = ();
}
求值
自由 常量始终在编译时 求值 以暴露 恐慌。即使在未使用的函数中也会发生这种情况:
#![allow(unused)]
fn main() {
// 编译时恐慌
const PANIC: () = std::unimplemented!();
fn unused_generic_function<T>() {
// 失败的编译时断言
const _: () = assert!(usize::BITS == 0);
}
}