一、变量声明语法
Rust 要求变量必须先声明后使用,这是其安全性的重要基础。局部变量的声明语法为:
rust
let var: i32 = 1;
由于 Rust 具有强大的类型推导功能,类型标注 :i32 通常可以省略,让编译器自动推断类型。
- 语法设计优势
Rust 的变量声明语法具有以下优势:
-
语法解析简单:let 关键字开头,类型后置,减少了语法歧义
-
类型推导友好:变量前置、类型后置的设计更适合类型推导(与VB语法相似)
注意:常量和静态变量必须显式声明类型,即使上下文能够推导出类型
- 模式解构
let 表达式不仅能绑定变量,还能进行复杂解构(与函数式语言相似):
rust
fn main() {
let (a, mut b): (bool, bool) = (true, false);
// a = true, 不可变; b = false, 可变
println!("a = {:?}, b = {:?}", a, b);
b = true;
assert_eq!(a, b);
}
三、变量命名规则
Rust 标识符(变量名、函数名等)规则:
-
由数字、字母、下划线组成
-
不能以数字开头
-
区分大小写
特殊用法:以下划线开头的变量可以避免"未使用变量"警告:
rust
fn main() {
let _x = 5; // 不会产生警告
let y = 10; // 会产生未使用警告
}
四、变量遮蔽(Variable Shadowing)
Rust 允许在同一作用域中声明同名变量:
rust
fn var_masking() {
let x = "1";
println!("{}", x); // 输出: 1
let x = 2; // 遮蔽前一个x
println!("{}", x); // 输出: 2
}
注意:变量遮蔽是安全的,因为它不会产生内存安全问题,只是创建了一个新变量。(与VB语法相似)
五、类型推导
Rust 的类型推导有两种方式:
rust
fn type_derivation() {
// 1. 通过字面量后缀推导
let x = 5u8; // 类型: u8
// 2. 通过默认整数类型推导
let y = 1; // 类型: i32
// 3. 通过上下文推导
let mut vec = Vec::new(); // 类型待定
vec.push(1); // 推导出: Vec<i32>
}
六、类型别名
使用 type 关键字创建类型别名:
rust
fn type_alias() {
type int = i32; // 创建别名
let x: int = 1; // 使用别名
println!("{}", x);
}
类型别名也支持泛型:
rust
type Double<T> = (T, Vec<T>);
// 使用: Double<i32> 等同于 (i32, Vec<i32>)
七、可变性(Mutability)
- 默认不可变
Rust 变量默认不可变,这是其安全模型的核心:
rust
fn variable_mut() {
let i = 123;
i = 2; // 编译错误:不能对不可变变量赋值
}
- 使用 mut 声明可变变量
rust
fn variable_mut() {
let mut i = 1; // 声明为可变
i = 2; // 现在可以修改
}
如果声明了 mut 但未修改变量,编译器会提示移除不必要的 mut。
八、静态变量
静态变量使用 static 关键字声明,具有全局生命周期:
rust
static GLOBAL: i32 = 0; // 静态变量声明
静态变量的特点:
-
必须在声明时初始化
-
初始化值必须是编译期常量
-
可变静态变量需要使用 unsafe 块访问
九、常量
常量使用 const 关键字声明:
rust
const PI: f64 = 3.1415; // 必须显式声明类型
常量命名规范:全部大写,下划线分隔单词(如 MAX_POINTS)
常量 vs 静态变量
特性 | 常量 | 静态变量 |
---|---|---|
可变性 | 永远不可变 | 可声明为可变 |
初始化 | 编译时确定 | 编译时确定 |
存储 | 可能直接嵌入代码 | 存储在静态数据段 |
作用域 | 可限制作用域 | 全局可见 |
十、常见错误
- 未初始化使用变量
rust
fn main() {
let x: i32; // 错误:未初始化
println!("{}", x); // 编译错误
}
- mut 与 const 冲突
rust
fn const_mut_error() {
const mut i: i32 = 1; // 错误:常量不能可变
}
- 使用下划线忽略未使用变量
rust
fn main() {
let a = 5; // 警告:未使用变量
let _b = 6; // 无警告:以下划线开头
}
十一、为什么需要手动设置可变性?
Rust 选择默认不可变的设计有多个原因:
-
安全性:防止意外修改,减少bug
-
并发友好:不可变数据天然线程安全,无需锁机制
-
性能优化:编译器可以对不可变数据进行更多优化
-
明确意图:mut 关键字明确表达了修改意图
这种设计与 Java 等语言的"默认可变,需要时加 final"形成对比,体现了 Rust"安全优先"的设计哲学。
十二、总结
Rust 的变量系统体现了语言的核心理念:
-
安全第一:默认不可变、必须初始化
-
明确表达:显式的可变性声明
-
灵活实用:变量遮蔽、类型推导、模式解构
-
零成本抽象:编译期检查,运行时无额外开销
掌握 Rust 的变量系统是学习这门语言的重要第一步,它为理解所有权、借用等更高级概念奠定了基础。