【Rust】 1. 变量学习笔记

一、变量声明语法

Rust 要求变量必须先声明后使用,这是其安全性的重要基础。局部变量的声明语法为:

rust 复制代码
let var: i32 = 1;

由于 Rust 具有强大的类型推导功能,类型标注 :i32 通常可以省略,让编译器自动推断类型。

  1. 语法设计优势

Rust 的变量声明语法具有以下优势:

  • 语法解析简单:let 关键字开头,类型后置,减少了语法歧义

  • 类型推导友好:变量前置、类型后置的设计更适合类型推导(与VB语法相似)

注意:常量和静态变量必须显式声明类型,即使上下文能够推导出类型

  1. 模式解构

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)

  1. 默认不可变

Rust 变量默认不可变,这是其安全模型的核心:

rust 复制代码
fn variable_mut() {
    let i = 123;
    i = 2;  // 编译错误:不能对不可变变量赋值
}
  1. 使用 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 静态变量
特性 常量 静态变量
可变性 永远不可变 可声明为可变
初始化 编译时确定 编译时确定
存储 可能直接嵌入代码 存储在静态数据段
作用域 可限制作用域 全局可见

十、常见错误

  1. 未初始化使用变量
rust 复制代码
fn main() {
    let x: i32;        // 错误:未初始化
    println!("{}", x); // 编译错误
}
  1. mut 与 const 冲突
rust 复制代码
fn const_mut_error() {
    const mut i: i32 = 1;  // 错误:常量不能可变
}
  1. 使用下划线忽略未使用变量
rust 复制代码
fn main() {
    let a = 5;    // 警告:未使用变量
    let _b = 6;   // 无警告:以下划线开头
}

十一、为什么需要手动设置可变性?

Rust 选择默认不可变的设计有多个原因:

  1. 安全性:防止意外修改,减少bug

  2. 并发友好:不可变数据天然线程安全,无需锁机制

  3. 性能优化:编译器可以对不可变数据进行更多优化

  4. 明确意图:mut 关键字明确表达了修改意图

这种设计与 Java 等语言的"默认可变,需要时加 final"形成对比,体现了 Rust"安全优先"的设计哲学。

十二、总结

Rust 的变量系统体现了语言的核心理念:

  • 安全第一:默认不可变、必须初始化

  • 明确表达:显式的可变性声明

  • 灵活实用:变量遮蔽、类型推导、模式解构

  • 零成本抽象:编译期检查,运行时无额外开销

掌握 Rust 的变量系统是学习这门语言的重要第一步,它为理解所有权、借用等更高级概念奠定了基础。