Rust 基础语法(长文解析)

Rust 基础语法:从零开始构建你的第一段安全代码

你是否曾被指针越界、空引用或内存泄漏困扰过?在现代编程语言中,Rust 正以“安全”与“高性能”的双轮驱动,逐渐成为系统级开发的新宠。它不像 C 语言那样“自由”,也不像 Python 那样“随意”,而是用一套严谨的规则,让你在编写高性能代码的同时,几乎不再需要担心运行时崩溃。

今天,我们就来深入探索 Rust 基础语法的核心内容。无论你是刚接触编程的新人,还是想尝试系统级开发的中级开发者,这篇文章都能帮你快速建立起对 Rust 的清晰认知。

Rust 基础语法不仅仅是关键字和语法糖的堆砌,它背后是一套关于所有权、借用和生命周期的哲学体系。但别担心,我们不会一上来就讲“所有权”,而是从最基础的变量声明、函数定义开始,像搭积木一样,一步步构建你的 Rust 知识大厦。


变量声明与类型推断

在 Rust 中,变量默认是不可变的,这是一条重要的设计哲学:“默认安全”。你必须显式声明变量为可变,才能修改它的值。

let name = "Alice";        // 不可变变量,编译器自动推断为 &str 类型
let mut age = 25;           // 可变变量,使用 mut 关键字声明
age = 26;                   // ✅ 合法:age 是可变的
// name = "Bob";           // ❌ 错误:name 是不可变的,不能重新赋值

注释let 用于声明变量,mut 表示“可变”。Rust 会根据赋值内容自动推断类型(类型推断),但你也可以显式声明,比如 let age: i32 = 25;

这种设计就像你家的抽屉:默认是锁住的,只有你主动打开(用 mut)才能放东西进去。这能有效防止意外修改,减少 bug。


数据类型与基本运算

Rust 提供了丰富的内置类型,涵盖整数、浮点数、布尔值、字符等。它们的命名清晰,且有明确的大小和范围。

类型 说明 示例值
i32 32 位有符号整数 -2147483648
u32 32 位无符号整数 4294967295
f64 64 位浮点数(默认) 3.14159
bool 布尔类型 true / false
char Unicode 字符 'A'
let x: i32 = 100;         // 显式声明为 i32
let y: f64 = 3.14;         // 浮点数默认是 f64
let is_valid = true;       // 布尔值
let first_letter = 'R';    // 字符类型,用单引号

// 基本运算
let sum = x + 5;           // 105
let product = y * 2.0;     // 6.28318
let is_greater = x > 50;   // true

注释:Rust 支持算术、比较、逻辑等常见运算。注意 f64 是默认浮点类型,精度更高,适合科学计算。


函数定义与参数传递

在 Rust 中,函数是代码复用的核心。定义函数使用 fn 关键字,参数和返回值都需要显式声明类型。

fn add(a: i32, b: i32) -> i32 {
    // 函数体
    a + b
}

fn main() {
    let result = add(10, 20);
    println!("10 + 20 = {}", result); // 输出: 10 + 20 = 30
}

注释fn 表示函数定义,a: i32 是参数,-> i32 表示返回值类型。Rust 中函数的最后一条表达式会自动作为返回值,无需写 return

你也可以在函数中使用更复杂的逻辑,比如条件判断:

fn check_age(age: u8) -> &'static str {
    if age >= 18 {
        "成年人"
    } else {
        "未成年人"
    }
}

fn main() {
    println!("{}", check_age(20)); // 输出: 成年人
    println!("{}", check_age(16)); // 输出: 未成年人
}

注释&'static str 是字符串字面量的引用,生命周期为整个程序运行期。这里用 &'static 表示字符串常量,无需担心内存释放。


控制流:if、while 与 for

Rust 的控制流语法简洁而强大。if 表达式在 Rust 中是“表达式”,可以赋值给变量。

fn main() {
    let number = 5;

    let result = if number % 2 == 0 {
        "偶数"
    } else {
        "奇数"
    };

    println!("{} 是 {}", number, result); // 输出: 5 是 奇数
}

注释if 后的条件不需要括号,但大括号是必需的。整个 if 块返回一个值,因此可以赋值给变量。

循环方面,whilefor 都很直观:

// while 循环
let mut count = 0;
while count < 5 {
    println!("count = {}", count);
    count += 1;
}

// for 循环:遍历范围
for i in 0..5 {
    println!("i = {}", i);
}

注释0..5 表示从 0 到 4 的半开区间,for 循环在 Rust 中是首选,因为更安全、更易读。


创建数组与初始化

数组在 Rust 中是固定长度的集合,类型和大小都必须在编译期确定。这就像你家的冰箱:每一格只能放一种东西,且数量不能变。

// 方法一:显式声明大小和类型
let numbers: [i32; 5] = [1, 2, 3, 4, 5];

// 方法二:用重复值初始化
let zeros = [0; 10];  // 创建一个包含 10 个 0 的数组

// 访问元素(下标从 0 开始)
println!("第一个元素: {}", numbers[0]); // 输出: 第一个元素: 1

注释[i32; 5] 表示长度为 5 的 i32 数组。[0; 10] 是语法糖,表示 10 个 0。访问数组时,Rust 会做边界检查,越界会直接 panic。

如果你想处理可变长度的数据,可以使用 Vec<T>(向量):

let mut scores = vec![85, 90, 78];     // 创建一个可变向量
scores.push(95);                       // 添加元素
println!("所有分数: {:?}", scores);    // 输出: 所有分数: [85, 90, 78, 95]

注释Vec<T> 是动态数组,可以自动扩容。push 方法用于添加元素,{} 中的 ? 表示打印格式,会显示完整结构。


结语:Rust 基础语法是通往安全编程的起点

Rust 基础语法看似简单,实则蕴含深刻的设计理念:“安全优先”。通过不可变变量、类型推断、函数表达式、边界检查等机制,Rust 在编译期就帮你消灭了大量常见的运行时错误。

从变量声明到函数定义,从控制流到数据结构,每一步都在训练你用更安全、更严谨的方式思考代码。这不仅是学习一门语言,更是重塑编程习惯。

当你能熟练使用这些语法元素时,你已经走出了学习 Rust 的第一步。接下来,你将面对所有权、借用检查器等更深层的概念,但它们都建立在这些基础之上。

所以,别急着跳过这些“简单”的语法,把它们练熟,就像练好基本功一样。未来的系统级开发、嵌入式编程、高性能服务,都可能由你用 Rust 亲手构建。

Rust 基础语法,不只是入门的钥匙,更是通往未来编程世界的通行证。