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块返回一个值,因此可以赋值给变量。
循环方面,while 和 for 都很直观:
// 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 基础语法,不只是入门的钥匙,更是通往未来编程世界的通行证。