Rust 知识图谱的基础部分 围绕核心语法、内存安全机制、数据结构与控制流展开
一、Rust 语言概述
Rust 是一门系统编程语言 ,由 Mozilla 开发(2010 年启动,2015 年发布 1.0 稳定版),设计目标是内存安全、高性能、并发安全。其核心特性包括:
- 内存安全 :通过所有权(Ownership) 、借用(Borrowing)、**生命周期(Lifetimes)**机制,在编译期避免空指针、数据竞争等内存错误;
- 高性能:与 C/C++ 相当,无垃圾回收(GC) overhead;
- 并发安全:所有权模型确保线程安全,无需手动加锁;
- 零成本抽象:高级语法(如 trait、泛型)不引入运行时性能损失。
Rust 适用于系统编程(操作系统、嵌入式)、高性能服务端、WebAssembly、区块链等场景。
二、基础语法
1. 变量与可变性
-
不可变变量 :默认情况下,变量不可变(值无法修改),需用
let声明:rustlet x = 5; // 不可变,x = 6 会报错 -
可变变量 :用
mut关键字声明,值可修改:rustlet mut y = 5; y = 6; // 合法 -
常量 :用
const声明,必须指定类型,值在编译期确定:rustconst MAX_NUM: u32 = 100; // 常量,不可修改 -
变量遮蔽(Shadowing) :允许用同一名称重新声明变量(类型可改变),区别于
mut(仅值可变):rustlet x = 5; let x = x + 1; // 遮蔽,x 变为 6(类型仍为 i32) let x = "hello"; // 再次遮蔽,x 变为字符串(类型改变)
2. 数据类型
Rust 是静态类型语言 (编译期需确定类型),分为标量类型 (单一值)和复合类型(多个值组合)。
(1)标量类型
- 整型 :表示整数,分为有符号(
i8/i16/i32/i64/i128/isize)和无符号(u8/u16/u32/u64/u128/usize),默认类型为i32(最快)。isize/usize:依赖架构(32 位系统为 32 位,64 位为 64 位),主要用于数组索引、指针运算。- 字面值:支持十进制(
98_222)、十六进制(0xff)、八进制(0o77)、二进制(0b111_000),可加后缀(如57u8)或用_分隔(如1_000)。
- 浮点型 :表示小数,分为
f32(单精度)和f64(双精度),默认类型为f64(精度更高,速度与f32相近)。 - 布尔型 :
bool,取值为true或false,用于条件判断。 - 字符型 :
char,表示 Unicode 标量值(如'A'、'中'、'😊'),占 4 字节,用单引号声明。
(2)复合类型
- 元组(Tuple) :将多个不同类型的值组合成一个类型,长度固定。
- 定义:
let tup = (500, 6.4, 'J');(类型(i32, f64, char)); - 访问:用模式匹配 解构(
let (x, y, z) = tup;)或索引 (tup.0,索引从 0 开始)。
- 定义:
- 数组(Array) :存储相同类型 的固定长度集合,分配在栈上(而非堆)。
- 定义:
let a = [1, 2, 3, 4, 5];(类型[i32; 5]); - 访问:用索引(
a[0]),若索引超出范围,Rust 会panic(避免越界访问)。
- 定义:
三、核心特性:所有权与借用
Rust 的内存安全核心机制,无需 GC 即可避免内存泄漏、悬垂指针等问题。
1. 所有权规则
-
唯一所有者:每个值有且仅有一个所有者(变量);
-
作用域释放 :所有者离开作用域时,值会被自动释放(调用
drop函数); -
所有权转移 :当值被赋值给另一个变量时,所有权会转移(原变量失效)。
示例:rustlet s1 = String::from("hello"); // s1 拥有字符串所有权 let s2 = s1; // 所有权转移给 s2,s1 失效(无法再使用) // println!("{}", s1); // 报错:s1 已失效
2. 借用与引用
-
不可变借用 :用
&声明,允许多个引用同时访问值,但不能修改 :rustlet s = String::from("hello"); let r1 = &s; // 不可变借用 let r2 = &s; // 多个不可变借用合法 println!("{} {}", r1, r2); // 合法 -
可变借用 :用
&mut声明,一次只能有一个可变引用 ,且不能与不可变引用共存 (避免数据竞争):rustlet mut s = String::from("hello"); let r3 = &mut s; // 可变借用 r3.push_str(", world"); // 合法(修改值) // let r4 = &s; // 报错:不可变引用与可变引用共存
3. 生命周期
生命周期是引用的有效范围 ,确保引用始终指向有效内存。Rust 编译器通过生命周期注解 (如 'a)检查引用的有效性,避免悬垂指针(如返回局部变量的引用)。
示例:
rust
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
if s1.len() > s2.len() { s1 } else { s2 }
}
上述函数中,'a 表示 s1、s2 和返回值的生命周期一致,确保返回的引用不会超过输入引用的有效范围。
四、控制流
Rust 支持常见的控制流结构,其中**if 是表达式**(返回值),循环用于重复执行代码。
1. if 表达式
-
条件无需括号,必须为
bool类型; -
可返回值(最后一个表达式的值),无需
return。
示例:rustlet number = 10; let result = if number > 5 { "大于5" // 表达式,返回值 } else { "小于等于5" }; println!("{}", result); // 输出:大于5
2. 循环
-
loop:无限循环,需用break退出(可返回值):rustlet mut counter = 0; let result = loop { counter += 1; if counter == 5 { break counter * 2; // 返回 10 } }; println!("{}", result); // 输出:10 -
while:条件为真时执行循环体:rustlet mut n = 3; while n > 0 { println!("{}", n); // 输出 3、2、1 n -= 1; } -
for:遍历集合(如数组、范围),最常用:rustfor i in 1..=5 { // 范围 1~5(包含 5) println!("{}", i); // 输出 1、2、3、4、5 } // 遍历数组 let arr = [10, 20, 30]; for num in arr.iter() { println!("{}", num); // 输出 10、20、30 }
3. match 表达式
match 是 Rust 的模式匹配 工具,用于匹配值并执行对应逻辑,必须覆盖所有可能的情况( exhaustive )。
示例:
rust
enum Direction { Up, Down, Left, Right }
let dir = Direction::Up;
match dir {
Direction::Up => println!("向上"),
Direction::Down => println!("向下"),
_ => println!("其他方向"), // 通配符,覆盖剩余情况
}
五、函数
函数是 Rust 程序的基本构建块,用 fn 关键字声明。
1. 函数定义
-
语法:
fn 函数名(参数: 类型) -> 返回值类型 { 函数体 }; -
参数必须指定类型(Rust 不支持类型推断的参数);
-
返回值:函数体最后一个表达式 的值(无分号),或用
return提前返回。
示例:rustfn add(a: i32, b: i32) -> i32 { a + b // 最后一个表达式,返回值(无分号) } fn main() { let result = add(3, 5); println!("{}", result); // 输出:8 }
2. 语句与表达式
-
语句 :执行操作但不返回值(如
let x = 5;、函数定义); -
表达式 :计算并返回值(如
a + b、if表达式、循环)。
示例:rustlet x = 5; // 语句(无返回值) let y = { // 代码块(表达式),返回最后一个表达式的值 let a = 3; a + 2 // 返回值 5(无分号) }; println!("{}", y); // 输出:5
六、错误处理
Rust 没有异常机制,用**Result和 Option**枚举处理错误。
1. Option 枚举
Option<T> 表示"有值"(Some(T))或"无值"(None),用于处理可能缺失的值。
示例:
rust
fn get_first_element(arr: &[i32]) -> Option<i32> {
if arr.is_empty() {
None // 无值
} else {
Some(arr[0]) // 有值
}
}
let arr = [10, 20, 30];
match get_first_element(&arr) {
Some(val) => println!("第一个元素:{}", val), // 输出:10
None => println!("数组为空"),
}
2. Result 枚举
Result<T, E> 表示"成功"(Ok(T))或"失败"(Err(E)),用于处理可恢复的错误(如文件读取失败)。
示例:
rust
use std::fs::File;
fn read_file(path: &str) -> Result<String, std::io::Error> {
let file = File::open(path)?; // ? 操作符:若出错,返回 Err
let content = std::io::read_to_string(file)?;
Ok(content) // 成功,返回 Ok(content)
}
fn main() {
match read_file("test.txt") {
Ok(content) => println!("文件内容:{}", content),
Err(e) => println!("错误:{}", e),
}
}
七、结构体与枚举
1. 结构体(Struct)
结构体是自定义数据类型,用于将多个相关值组合成一个类型(类似 C 的结构体)。
-
定义:
struct 结构体名 { 字段名: 类型, ... }; -
实例化:用
{ 字段名: 值, ... }初始化; -
方法:用
impl块定义,可访问结构体字段。
示例:ruststruct User { username: String, email: String, sign_in_count: u64, active: bool, } impl User { // 关联函数(类似构造函数) fn new(username: String, email: String) -> User { User { username, email, sign_in_count: 0, active: true, } } // 方法(&self 表示不可变引用) fn get_username(&self) -> &str { &self.username } } fn main() { let user = User::new(String::from("alice"), String::from("alice@example.com")); println!("用户名:{}", user.get_username()); // 输出:alice }
2. 枚举(Enum)
枚举是多 variant 类型,用于表示"多种可能的情况"(类似 C 的枚举,但更强大)。
-
定义:
enum 枚举名 { Variant1, Variant2, ... }; -
variant 可携带数据(如
IpAddrKind::V4(String))。
示例:rustenum IpAddr { V4(String), // IPv4 地址(字符串) V6(String), // IPv6 地址(字符串) } let home = IpAddr::V4(String::from("127.0.0.1")); let work = IpAddr::V6(String::from("::1")); // 模式匹配处理枚举 match home { IpAddr::V4(addr) => println!("IPv4:{}", addr), // 输出:127.0.0.1 IpAddr::V6(addr) => println!("IPv6:{}", addr), }
总结
Rust 知识图谱的基础部分涵盖:
- 语言概述:定位、特性与应用场景;
- 基础语法:变量、数据类型(标量/复合)、函数;
- 核心机制:所有权、借用、生命周期(内存安全的关键);
- 控制流 :
if、loop、while、for、match; - 错误处理 :
Option、Result; - 数据结构:结构体、枚举。
这些内容是学习 Rust 的基石,后续的泛型、trait、并发 等高级特性均基于此展开。建议通过实践(如编写小项目、解决 LeetCode 题)巩固基础,逐步深入理解 Rust 的设计思想。