常量条目

语法
常量条目 :
   const ( 标识符 | _ ) : 类型 ( = 表达式 )? ;

常量条目 是一个可选名称的、不与程序中特定内存位置关联的 常量值 。 常量在使用时本质上是内联的,这意味着当它们在相关上下文中使用时,会被直接拷贝。 这包括使用来自外部 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);
}
}