Rust - 常量
Rust - 常量
Section titled “Rust - 常量”常量是绑定到一个名称且不允许更改的值。在 Rust 中,常量使用 const 关键字声明,并且它们的类型必须始终被注解(annotated)。
const MAX_POINTS: u32 = 100_000;命名约定和作用域
Section titled “命名约定和作用域”常量的命名约定是使用所有大写字母,单词之间用下划线分隔(SCREAMING_SNAKE_CASE)。常量可以在任何作用域中声明,包括全局作用域,这使得它们对于程序多个部分共享的值非常有用。
const SECONDS_IN_MINUTE: u32 = 60;const MINUTES_IN_HOUR: u32 = 60;const SECONDS_IN_HOUR: u32 = SECONDS_IN_MINUTE * MINUTES_IN_HOUR;
fn main() { println!("There are {} seconds in an hour.", SECONDS_IN_HOUR);}There are 3600 seconds in an hour.const 和不可变 let 之间的区别
Section titled “const 和不可变 let 之间的区别”你可能会想,既然 Rust 默认就有不可变变量(let),为什么还需要常量呢?虽然它们看起来相似,但存在重要的区别:
- 类型注解:你必须注解
const的类型。而let通常可选,因为编译器可以推断它。 - 可变性:
const值永远不能通过mut变为可变。虽然let绑定默认是不可变的,但它们可以用mut标记。 - 评估时间:
const必须设置为一个常量表达式,即编译器在编译时可以确定的值。它不能是函数调用或任何在运行时计算的值的结果。 - 内联:
const值在代码中使用的地方实际上会被内联。这意味着const没有单个内存地址。 - 作用域:
const可以在任何作用域中声明,包括全局。let仅限于函数或块作用域。
代码示例:编译时 vs. 运行时
Section titled “代码示例:编译时 vs. 运行时”fn get_runtime_value() -> u32 { // 某些复杂计算... 5}
fn main() { // 这有效:该值在编译时计算。 const COMPILE_TIME_VALUE: u32 = 5 * 2;
// 这无效:该值在运行时计算。 // const RUNTIME_VALUE: u32 = get_runtime_value(); // 错误:常量中的函数调用仅限于常量函数
// 不可变变量适用于运行时值。 let runtime_variable = get_runtime_value();
println!("Compile-time: {}, Runtime: {}", COMPILE_TIME_VALUE, runtime_variable);}static 注解
Section titled “static 注解”Rust 还有另一种创建在程序整个生命周期内都存在的值的方式:static 变量。与 const 不同,static 变量有一个固定的内存位置。static 变量也可以是可变的(使用 static mut),但访问或修改可变 static 变量是 unsafe(不安全)的,因为它可能引入数据竞争(data races)。对于永不改变的值,const 几乎总是更好的选择。
static HELLO_WORLD: &str = "Hello, world!";
fn main() { println!("Static says: {}", HELLO_WORLD);}不允许对常量进行遮蔽
Section titled “不允许对常量进行遮蔽”与用 let 声明的变量不同,常量不能被遮蔽(shadowed)。尝试在同一作用域中声明同名的另一个常量将导致编译时错误。
fn main() { const NAME: &str = "Alice"; // 下面这行代码会导致编译错误: // const NAME: usize = 0; // error[E0260]: 名称 `NAME` 已多次定义
println!("Name is {}", NAME);}