Rust 中的不可变变量和 const 变量有什么区别?

问题描述 投票:0回答:7

我了解到,如果一个变量没有使用

mut
显式声明为可变的,它就会变得不可变(声明后不能更改)。那么为什么 Rust 中有
const
关键字呢?它们不是一样的吗?如果不是,它们有何不同?

rust constants immutability
7个回答
101
投票

const
,在 Rust 中是 constant 的缩写,与 编译时评估 相关。它显示:

  • 声明常量时:
    const FOO: usize = 3;
  • 声明编译时可评估函数时:
    const fn foo() -> &'static str

这些类型的值可以用作通用参数:

[u8; FOO]
。目前这仅限于数组大小,但有讨论、计划并希望将来进一步扩展。

相比之下,

let
绑定是关于运行时计算值的。

请注意,尽管使用

mut
是因为可变性的概念众所周知,但 Rust 实际上就在这里。
&T
&mut T
是关于别名,而不是可变性:

  • &T
    :共享参考
  • &mut T
    :独特参考

最值得注意的是,某些类型具有内部可变性,可以通过

&T
(共享引用)进行突变:
Cell
RefCell
Mutex


注意:

mut
const
与原始指针(
*mut T
*const T
)还有另一种用法,这里不讨论。


37
投票

const
不适用于变量;它用于可能不存储在任何地方的常量值;它们实际上是文字值的别名。

Non-

mut
let
声明一个在运行时创建的实际变量,可以移动(并且不再可访问),甚至在某些情况下具有内部可变性(例如,如果它包含
Cell
成员)。


23
投票

A

const
不代表内存位置,而是代表值。
const
值直接内联在其使用位置。在表达式求值期间创建的任何临时对象只能由编译器在编译时访问。可以在全球范围内进行。无法引用运行时项目。必须有类型注释。

让值代表一个内存位置。

let
绑定的不变性是编译器强制执行的,可以使用
mut
修饰符进行更改。它是运行时构造。始终在本地范围内。它们的类型可以由编译器推断。

为了完整起见,

static
也表示像let一样的内存位置,但对同一静态的任何引用实际上都是对同一内存位置的引用。静态就是静态。它们被编译为可执行文件,并在运行程序的整个生命周期内可访问。可以在全球范围内进行。可以参考其他静力学。必须有类型注释。


16
投票

常量不能被遮蔽:

let x = 10u32;
const Y:u32 = 20u32;

let x = 11u32;
//error: duplicate definition of value `Y` [E0428]
//const Y:u32 = 21u32;

println!("x={} Y={}",x,Y); //x=11 Y=20

8
投票

此外,我们无法使用 let 来创建全局项,但可以使用 const 来创建全局项。这是一个例子。

const LENGTH:usize = 4;

fn main() {
    let arr:[i32; LENGTH] = [10,20,30,40];

    for i in 0..LENGTH{
        println!("{}", arr[i])
    }
}

有关 conststaticlet 用法的更多信息:

const
static

故事有点长。


3
投票

const
用于编译时常量及其所需的一切。例如,您可以创建一个大小为
const
的固定大小数组,但不能使用
let
绑定来做到这一点。当然,这也意味着您可以将更多的东西放入
let
绑定中,而不是放入
const
中。


3
投票

从概念上讲,

const
项在解析之前被替换,类似于 C 宏的作用。这使得它可以在不允许使用普通变量的情况下使用。

const TEN: u32 = 10;
let ten = 10;

// OK
match x {
    TEN => do_a(),
    _ => do_b(),
}

// Nah...
match x {
    ten => do_a(),
    _ => do_b(),
}

// ...use this instead
match x {
    y if x == ten => do_a(),,
    _ => do_b(),
}
© www.soinside.com 2019 - 2024. All rights reserved.