Rust 基础语法
以下是用中文详细讲解 Rust 编程语言的基础语法,涵盖变量、数据类型、控制流、函数、结构体、枚举等核心概念,适合初学者快速入门。内容将简洁明了,配以示例代码,确保易于理解。
1. 变量与常量
Rust 是静态类型语言,变量默认不可变,需使用 mut
关键字声明可变变量。
1.1 变量
- 不可变变量:使用
let
声明,默认不可变。 - 可变变量:使用
let mut
声明。 - 类型推断:Rust 编译器会自动推断变量类型,也可显式指定。
示例:
fn main() {
let x = 42; // 不可变变量,类型推断为 i32
let mut y: i32 = 100; // 可变变量,显式指定类型
// x = 43; // 错误:不可变变量不能重新赋值
y = 200; // 正确:可变变量可以重新赋值
println!("x = {}, y = {}", x, y);
}
1.2 常量
使用 const
声明,必须显式指定类型,且值在编译时确定。
示例:
const MAX_VALUE: i32 = 1000;
fn main() {
println!("最大值: {}", MAX_VALUE);
}
说明:
- 常量不可变,且不能用
mut
。 - 常量通常用于全局固定值。
1.3 遮蔽(Shadowing)
可以在同一作用域内重新声明同名变量,覆盖之前的定义。
示例:
fn main() {
let x = 5;
let x = x + 1; // 遮蔽,x 现在是 6
{
let x = x * 2; // 内部作用域,x 现在是 12
println!("内部 x: {}", x);
}
println!("外部 x: {}", x); // 仍然是 6
}
2. 数据类型
Rust 提供标量类型和复合类型,类型安全由编译器严格检查。
2.1 标量类型
- 整数:
i8
,i16
,i32
,i64
,i128
(有符号),u8
,u16
,u32
,u64
,u128
(无符号),isize
,usize
(与系统架构相关)。 - 浮点数:
f32
,f64
。 - 布尔值:
bool
(true
或false
)。 - 字符:
char
(Unicode 字符,4 字节)。
示例:
fn main() {
let int: i32 = -42;
let uint: u32 = 100;
let float: f64 = 3.14;
let boolean: bool = true;
let character: char = '中';
println!("整数: {}, 无符号整数: {}, 浮点数: {}, 布尔: {}, 字符: {}", int, uint, float, boolean, character);
}
2.2 复合类型
- 元组(Tuple):固定长度,元素类型可不同。
- 数组:固定长度,元素类型相同。
示例:
fn main() {
// 元组
let tup: (i32, f64, char) = (42, 3.14, 'a');
let (x, y, z) = tup; // 解构
println!("元组: x = {}, y = {}, z = {}", x, y, z);
println!("通过索引访问: {}", tup.0); // 访问第一个元素
// 数组
let arr: [i32; 3] = [1, 2, 3];
println!("数组: {:?}", arr); // 使用调试格式输出
println!("数组第一个元素: {}", arr[0]);
}
说明:
- 元组用
.
索引(如tup.0
)。 - 数组索引从 0 开始,越界访问会引发编译期或运行时错误。
3. 函数
Rust 函数使用 fn
关键字定义,参数和返回值需显式声明类型。
示例:
fn main() {
greet("Alice"); // 调用函数
let sum = add(5, 10);
println!("5 + 10 = {}", sum);
}
fn greet(name: &str) { // 无返回值
println!("你好, {}!", name);
}
fn add(a: i32, b: i32) -> i32 { // 返回 i32 类型
a + b // 隐式返回(不加分号)
}
说明:
- 函数参数需指定类型。
- 返回值类型用
->
指定。 - 最后表达式(无分号)作为返回值,
return
可用于提前返回。
4. 控制流
Rust 提供分支和循环结构,支持条件判断和迭代。
4.1 条件语句(if)
示例:
fn main() {
let number = 7;
if number > 5 {
println!("大于 5");
} else if number == 5 {
println!("等于 5");
} else {
println!("小于 5");
}
// if 作为表达式
let condition = true;
let result = if condition { 10 } else { 20 };
println!("result = {}", result);
}
说明:
if
条件不需括号,但代码块需用{}
。if
可用作表达式,返回值类型必须一致。
4.2 循环
Rust 提供三种循环:loop
、while
和 for
。
示例:
fn main() {
// loop(无限循环)
let mut count = 0;
loop {
if count >= 3 {
break; // 退出循环
}
println!("loop: {}", count);
count += 1;
}
// while
let mut number = 3;
while number > 0 {
println!("while: {}", number);
number -= 1;
}
// for 循环遍历
for i in 0..3 { // 0 到 2
println!("for: {}", i);
}
}
输出:
loop: 0
loop: 1
loop: 2
while: 3
while: 2
while: 1
for: 0
for: 1
for: 2
说明:
loop
用于无限循环,需用break
退出。while
基于条件循环。for
常用于迭代范围(如0..3
)或集合。
5. 所有权与借用
所有权是 Rust 的核心特性,确保内存安全。
5.1 所有权规则
- 每个值有且仅有一个所有者。
- 当所有者超出作用域时,值会被销毁(释放内存)。
- 值可以转移(move)或借用。
示例:
fn main() {
let s1 = String::from("hello"); // s1 拥有字符串
let s2 = s1; // 所有权转移,s1 失效
// println!("{}", s1); // 错误:s1 已失效
println!("{}", s2); // 正确
}
5.2 借用
- 使用
&
创建引用(借用),不转移所有权。 - 可变借用用
&mut
,但同一作用域内只能有一个可变借用。
示例:
fn main() {
let mut s = String::from("hello");
let r1 = &s; // 不可变借用
let r2 = &mut s; // 可变借用
// println!("{}", r1); // 错误:不可变借用与可变借用不能共存
r2.push_str(", world");
println!("{}", r2);
}
说明:
- 借用规则防止数据竞争,编译器严格检查。
- 不可变借用(
&
)允许多个,访问只读。 - 可变借用(
&mut
)只能有一个,允许修改。
6. 结构体(Struct)
结构体用于定义自定义数据类型。
示例:
struct User {
name: String,
age: u32,
active: bool,
}
fn main() {
let mut user = User {
name: String::from("Alice"),
age: 25,
active: true,
};
user.age = 26; // 修改字段
println!("姓名: {}, 年龄: {}, 活跃: {}", user.name, user.age, user.active);
// 结构体更新语法
let user2 = User {
name: String::from("Bob"),
..user // 复制 user 的其余字段
};
println!("用户2: {}", user2.name);
}
说明:
- 结构体字段通过
.
访问。 ..
用于复制结构体部分字段。
7. 枚举(Enum)
枚举用于定义一组相关值。
示例:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
fn main() {
let msg = Message::Write(String::from("hello"));
match msg {
Message::Quit => println!("退出"),
Message::Move { x, y } => println!("移动到 ({}, {})", x, y),
Message::Write(text) => println!("写入: {}", text),
}
}
说明:
- 枚举可以包含不同类型的数据。
- 使用
match
模式匹配处理枚举值。
8. 错误处理
Rust 使用 Option
和 Result
处理可能失败的操作。
8.1 Option
表示值可能存在或不存在。
示例:
fn main() {
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;
match some_value {
Some(x) => println!("值: {}", x),
None => println!("无值"),
}
}
8.2 Result
表示操作可能成功或失败。
示例:
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
match f {
Ok(file) => println!("文件打开成功: {:?}", file),
Err(err) => println!("错误: {}", err),
}
}
说明:
Option
用于处理可能为空的值。Result
用于处理可能出错的操作。?
运算符可简化错误传播。
9. 总结
Rust 基础语法包括:
- 变量:
let
、let mut
、const
,支持遮蔽。 - 数据类型:标量(整数、浮点、布尔、字符)、复合(元组、数组)。
- 函数:使用
fn
,支持隐式返回值。 - 控制流:
if
、loop
、while
、for
,支持表达式。 - 所有权与借用:确保内存安全的核心机制。
- 结构体和枚举:定义自定义类型,配合
match
使用。 - 错误处理:
Option
和Result
提供安全处理机制。
通过以上内容,你可以开始编写简单的 Rust 程序。如果需要更深入的讲解(如模块系统、闭包、trait 等)或具体示例,请告诉我!