Rust 变量
变量(variable)就是你给一个值起的名字,方便以后使用。可以把它想象成一个贴了标签的盒子:你把东西放进盒子,在上面写个名字,之后就用这个名字来指代它,不必到处重复写那个值。
在 Rust 里,用 let 关键字创建变量:
fn main() { let age = 30; println!("我今年 {age} 岁");}输出:
我今年 30 岁把这一行拆开来看:
let:告诉 Rust“我要创建一个新变量”。age:我们起的名字。=:把右边的值赋给左边的名字。30:要存的值。
println! 里的 {age} 会打印出这个变量的值。这叫作字符串插值(string interpolation):Rust 会把 {age} 替换成 age 里存的值。
Rust 会帮你推断类型
Section titled “Rust 会帮你推断类型”Rust 里的每个值都有一个类型(整数、文字、true/false 等等)。你可能以为得自己声明类型,但通常不用:Rust 会看着值自己推断出来。这叫作类型推断(type inference)。
fn main() { let score = 95; // Rust 推断出这是整数 let name = "Ferris"; // Rust 推断出这是文字 let is_active = true; // Rust 推断出这是布尔值 println!("{name}:{score} 分,在线 = {is_active}");}输出:
Ferris:95 分,在线 = true如果想写得明确一些,可以在冒号后面写上类型:
let score: i32 = 95; // i32 = 32 位整数变量默认不可变
Section titled “变量默认不可变”从其他语言转过来的人常常会被这一点吓一跳:在 Rust 里,变量一旦赋值,默认就不能再改。“不可变”(immutable)的意思就是不能被修改。
下面这段代码无法编译:
fn main() { let count = 1; count = 2; // ❌ 错误:不能对不可变变量赋值两次 println!("{count}");}编译器会用一条清楚的信息拦住你:
error[E0384]: cannot assign twice to immutable variable `count`意思是:不能对不可变变量 count 赋值两次。为什么一门语言要故意这样设计?因为很多 bug 都来自值在你没想到的时候被改掉了。除非你主动要求可以修改,否则一律不许改,这样 Rust 让你的代码更容易预测。这是一个特性,而不是限制。
用 mut 让变量可以修改
Section titled “用 mut 让变量可以修改”当你确实需要修改某个值时,加上 mut 关键字(mutable 的缩写,意思是“可变的”):
fn main() { let mut count = 1; println!("修改前:{count}");
count = 2; // ✅ 现在可以了,因为有 `mut` println!("修改后:{count}");}输出:
修改前:1修改后:2遮蔽:重复使用同一个名字
Section titled “遮蔽:重复使用同一个名字”Rust 允许你用和旧变量相同的名字声明一个新变量。这叫作遮蔽(shadowing):新变量把旧变量“挡住”了:
fn main() { let x = 5; let x = x + 1; // 一个新的 x,基于旧的 x -> 6 let x = x * 2; // 又一个新的 x -> 12 println!("x 是 {x}");}输出:
x 是 12这看起来和 mut 很像,但其实不一样:
mut修改的是同一个变量的值。- 遮蔽创建的是一个全新的变量,只是碰巧用了同一个名字,而且它甚至可以是不同的类型。
想对一个值做转换、但又想继续用同一个名字时,遮蔽就很方便:
fn main() { let spaces = " "; // 文字 let spaces = spaces.len(); // 现在是一个数字(有几个空格) println!("空格的个数:{spaces}");}输出:
空格的个数:3常量(constant)是一个永远不会改变、在编译时就确定下来的值。声明常量用 const 而不是 let,而且必须写上类型:
const MAX_SCORE: u32 = 100;
fn main() { println!("最高分是 {MAX_SCORE}");}输出:
最高分是 100按照惯例,常量名用 UPPER_SNAKE_CASE(全大写加下划线)书写。下面是常量和普通变量的对比:
let 变量 |
const 常量 |
|
|---|---|---|
| 能修改吗? | 只有加了 mut 才能 |
永远不能 |
| 必须写类型吗? | 可选(会自动推断) | 必须 |
| 命名风格 | snake_case |
UPPER_SNAKE_CASE |
| 能写在哪里 | 函数内部 | 任何地方,函数外面也可以 |
真正固定不变的值就用常量,比如一分钟有多少秒,或者某个上限。
- 使用
snake_case:小写单词之间用下划线连接,比如user_name、total_price。 - 名字可以包含字母、数字和下划线,但不能以数字开头。
- 起一个能说明含义的名字:
age比a好。
创建一个变量 level,初始值为 1。打印它,然后把它加 1,重复两次,每次修改后都打印一次,最终得到 等级 1、等级 2、等级 3。提示:会改变的值需要 mut,level = level + 1; 会让它加一。
查看答案
fn main() { let mut level = 1; println!("等级 {level}");
level = level + 1; println!("等级 {level}");
level = level + 1; println!("等级 {level}");}输出:
等级 1等级 2等级 32. 分钟换算成秒
Section titled “2. 分钟换算成秒”声明一个常量 SECONDS_PER_MINUTE,值为 60。先写 let time = 5;(单位是分钟),然后遮蔽 time,让它存放以秒为单位的同一段时长,并打印 也就是 300 秒。提示:新的 time 可以由旧的算出来:let time = time * ...;。
查看答案
const SECONDS_PER_MINUTE: u32 = 60;
fn main() { let time = 5; // 分钟 let time = time * SECONDS_PER_MINUTE; // 一个新的 `time`,现在单位是秒 println!("也就是 {time} 秒");}输出:
也就是 300 秒不需要 mut:第二个 let 创建了一个全新的变量,只是沿用了原来的名字。Rust 还会推断出这里的 time 是 u32,因为它和 u32 类型的常量相乘。
- 用
let创建变量;Rust 通常会帮你推断类型。 - 变量默认不可变,加上
mut才能修改。 - 遮蔽是用
let重新声明同一个名字,创建一个新变量(类型也可以变)。 - 常量(
const)永远不变,必须写类型,命名用UPPER_SNAKE_CASE。
小测验
1. 在 Rust 里,默认情况下能给 let 变量重新赋值吗?
2. Rust 中的遮蔽(shadowing)是什么?
3. 根据本页内容,Rust 变量用哪种命名风格?
得分: 0 / 3
- 变量和可变性 —《Rust 程序设计语言》:官方教程中讲
let、mut、常量以及为什么默认不可变的章节。 - 遮蔽 —《Rust 程序设计语言》:进一步说明遮蔽和
mut的区别,包括改变值的类型。 - 变量绑定 —《通过例子学 Rust》:简短的可运行示例,后续还有可变性和作用域和遮蔽两节。
- 常量 —《通过例子学 Rust》:在一个小程序里演示
const(以及它的近亲static)。 let关键字 — 标准库文档(英文):let能做的所有事情,想了解全貌时再看。