Rust 笔记Rust 语言中的常量与变量
1. 概述:常量与变量的概念
这一小节主要是为方便刚刚学编程的小白读者准备的。在计算机编程中常量和变量都是用于存储数据的标识符,它们用于表示在程序执行过程中可能发生变化的值。常量和变量的区别在于它们的赋值后的行为:即是否可以再改变。
1.1 常量 的概念
常量 是一个在程序执行期间值不会改变的标识符。常量通常用于表示在程序中固定不变的值,如数学常数、配置参数等。一旦常量被赋值,就无法再修改其值。
1.2 变量 的概念
变量 是一个在程序执行期间其值可以改变的标识符。变量通常用于表示在程序中需要存储、修改或计算的值。变量的值可以在程序的不同位置进行修改,允许根据需要动态调整存储的数据。
2. Rust 中的常量
2.1 定义常量
在 Rust 中,常量使用 const 关键字进行定义。常量的值在编译时就确定,并且不允许在程序执行期间更改。在 Rust 中定义的常量在 整个程序的作用域内 都有效。例如:
const MAX_COUNT: u32 = 100_000;
上面的这个常量的命名是遵循 Rust 语言常量命名规范的命名方式。
在 Rust 语言中,常量的命名规范通常使用全大写字母,单词之间使用 下划线 (_
) 进行分隔,这与 Python 语言中命名一个不在代码中改变的量的规范很像。不过 Python 中并没有真正意义上的常量,这个“不会改变”只存在与编程者头脑的契约中,而如果对 Rsut 中的常量进行修改,是回导致异常的。
2.2 Rsut 中常量的若干规则
常量的 类型 必须在 声明 时就明确指定,并且常量的值必须是一个编译时常量(在编译时可以确定其值)。这意味着不能将函数调用的结果或运行时计算的值赋给常量。
常量在 Rust 中的使用方式与变量类似,可以在表达式中使用常量,传递给函数,作为模式匹配的一部分等。
3. Rust 中的变量
3.1 定义变量
在 Rust 中,变量使用 let
关键字进行定义。变量的值可以根据需要在程序执行过程中进行修改。例如:
fn main() { let name = "Jack Lee"; let age: u32 = 27; println!("姓名: {}", name); println!("年龄: {}", age); }
输出结果为:
姓名: Jack Lee 年龄: 27
3.2 “不可变”的变量
3.2.1 违背常理的变量
你觉得你定义的变量可以修改吗?
看到本小节以这样的方式开头可能回让你有点以外——嗯,甚至有点 不安 和 疑惑:
既然是变量,那还问什么是否可以修改吗。想到这里,你不妨试试修改并运行一下你的代码:
fn main() { let name = "Jack Lee"; let age: u32 = 27; age = age-1; println!("姓名: {}", name); println!("年龄: {}", age); }
似乎有情况发生了,你看到的是下面这样的报错:
error[E0384]: cannot assign twice to immutable variable `age` --> src\main.rs:5:5 | 3 | let age: u32 = 27; | --- | | | first assignment to `age` | help: consider making this binding mutable: `mut age` 4 | 5 | age = age-1; | ^^^^^^^^^^^ cannot assign twice to immutable variable For more information about this error, try `rustc --explain E0384`. error: could not compile `use-reg` due to previous error
依据提示你可以查询一下 E0384:
rustc --explain E0384
你会看到:
An immutable variable was reassigned. Erroneous code example: fn main() { let x = 3; x = 5; // error, reassignment of immutable variable } By default, variables in Rust are immutable. To fix this error, add the keyword `mut` after the keyword `let` when declaring the variable. For example: fn main() { let mut x = 3; x = 5; }
上面清楚地告诉你:
一个不可变变量被重新分配!
(An immutable variable was reassigned.)
3.2.2 不可变背后的考虑
是的!——虽然被叫做变量。但是默认情况下,Rust中的变量是不可变的。为什么 Rust 要设计出这种违背常理的逻辑呢?
实际上将变量声明为不可变的,其目的在于 提供更强的安全性和防止潜在的错误。这种设计选择是 Rust 语言为了避免一类常见的编程错误,即 数据竞争(data races)。
关于 数据竞争 的概念
数据竞争 是指 多个线程 同时访问 共享数据,并且至少有一个线程试图写入该数据的情况。在并发编程中,数据竞争是非常危险的,因为它会导致不确定的行为、不可预测的结果以及安全漏洞。
不可变的其它优势
此外,Rust 语言中将变量默认为不可变还有以下优势:
- 易于推理:
不可变变量可以帮助程序员更容易地跟踪变量的状态和使用。由于不可变变量的值在绑定后不会发生改变,可以更加自信地推理代码的行为。 - 预防错误:
Rust 通过将变量默认声明为不可变的,鼓励程序员在编写代码时更加谨慎地处理数据共享和并发访问。当变量是不可变的时候,编译器可以进行更多的静态分析和优化,以确保并发访问的安全性。在编译时,Rust 编译器会检查对不可变变量的修改尝试,并在发现错误时发出错误信息。这可以帮助早期发现潜在的错误,减少调试和维护的难度。 - 提高可读性:
通过将变量声明为不可变的,代码的意图更加清晰明了。其他开发人员可以更容易地理解和维护你的代码,减少潜在的错误。
3.3 可变变量 与 mut 关键字
既然我们定义变量,那么就希望能够在某些时候改变它们。如果变量完完全全不可变,那就只需要常量好了。因此 Rust 也提供了 mut
关键字,使我们能够 显式地 将一个变量声明为 可变变量 以满足 修改数据 的需求。我们通过将 mut
关键字 放在变量名之前,可以指示编译器允许对该变量进行修改,例如,我们之前地例子中由于对不可变变量 age
做了修改导致于程序报错,现在只需为变量 age
加上 mute
关键字就能让程序正常运行:
fn main() { let name = "Jack Lee"; let mut age: u32 = 27; age = age-1; println!("姓名: {}", name); println!("年龄: {}", age); }
其输出结果为:
姓名: Jack Lee 年龄: 26
这个例子表名,本文作者 Jack Lee 由于生活很开心,越活越年轻,又年轻了一岁😊。