1.字符串(切片)
1. 基本概念
- 切片(Slice):指向集合中一段连续元素的引用,无所有权,只借用。
- 字符串切片:
&str,对String的部分 / 全部引用,只读。 - 底层:胖指针= 数据指针 + 长度。
2. 类型区别
| 类型 | 所有权 | 可变性 | 用途 |
|---|---|---|---|
String | 有 | 可变 | 需要修改、增长、拥有字符串 |
&str | 无 | 只读 | 函数参数、读取、子串、高效 |
字符串字面量
"hello"本质是&'static str(静态生命周期,全程有效)。
3. 切片语法(左闭右开)
let s = String::from("hello rust"); // 完整写法 let a = &s[0..5]; // hello // 简写 let b = &s[6..]; // rust(从6到末尾) let c = &s[..5]; // hello(从头到5) let d = &s[..]; // 整个字符串 &str4. 重要规则
切片索引按
UTF-8 字节
计算,
中文直接切片会 panic
let s = "你好"; // &s[0..1] ❌ 错误:中文占3字节,切片会断裂字符切片生命周期依附原 String,原字符串失效切片也无效。
同时存在 ** 不可变引用(切片)** 时,不能修改原字符串。
5. 函数最佳实践
参数优先用&str,兼容String、&String、字符串字面量:
// ✅ 通用 fn print(s: &str) { println!("{}", s); } fn main() { let s1 = "literal"; let s2 = String::from("owned"); print(s1); print(&s2); }6. 常用转换
String→&str:&s或s.as_str()&str→String:s.to_string()或String::from(s)
7. 一句话总结
&str 是只读借用,高效安全;String 是拥有所有权,可修改。函数参数一律用 &str。
2. 元组
1. 精简概念
元组是 Rust基础复合类型,可装不同类型的值,长度固定,不可增删改长度。
2. 定义(创建)
用小括号()包裹,元素用逗号分隔。
// 自动推导类型 let tup = (100, 3.14, 'a', true); // 显式标注类型 let tup: (i32, f64, char, bool) = (100, 3.14, 'a', true);3. 赋值与修改
元素可修改,但必须是可变变量,且类型不能变。
let mut tup = (1, 2); tup.0 = 10; // 正确 // tup.0 = 3.14; 错误:类型不匹配4. 获取值(两种方法)
① 点 + 索引(从 0 开始)
let tup = (10, 20, 30); let a = tup.0; // 10 let b = tup.1; // 20 let c = tup.2; // 30② 解构(模式匹配)
let tup = (100, "hello"); let (x, y) = tup; // x = 100, y = "hello"5. 一句话记住
- 元组:不同类型、固定长度
- 定义:
(值1, 值2) - 取值:
tup.0或let (a,b) = tup
3.结构体
1. 经典结构体(最常用,命名字段)
- 语法:
struct 名称 { 字段名: 类型, ... }(大驼峰命名) - 实例化:
let 实例 = 名称 { 字段: 值, ... } - 访问:
实例.字段名;可变实例(mut)可修改字段 - 简写:变量名 = 字段名时,可省略(
User { username, email }) - 更新语法:
let 新实例 = 旧实例 { 字段: 新值, ..旧实例 }(保留其余字段)
2. 元组结构体(Tuple Struct,无字段名、按位置)
- 语法:
struct Color(i32, i32, i32); - 实例化:
let c = Color(255, 0, 0); - 访问:下标
.0/.1/.2、模式匹配解构(let Color(r,g,b)=c)、整体当元组拆包
3. 单元结构体(Unit Struct,无字段、零大小)
- 语法:
struct Marker; - 实例化:
let m = Marker; - 用途:标记类型、实现 trait 占位、无需存储数据时使用
4.关键规则与细节
- 所有权:结构体默认拥有字段所有权;用引用(
&str/&T)需生命周期(后续章节) - 可见性:默认私有;加
pub公开结构体 / 字段(pub struct User; pub username: String) - 内存:字段连续存储,编译器自动对齐(padding),保证访问效率
- 与元组区别:struct 有类型名、可封装方法;元组无类型名、仅临时组合
4. 枚举
1. 基本定义
- 使用
enum关键字定义一组命名的值,每个值叫变体(variant) - 变体可以不带数据、带元组数据、带结构体数据
enum IpAddr { V4, V6, }2. 枚举变体可以携带数据
- 元组型
- 结构体命名字段型
- 每个变体可以是不同类型
enum Message { Quit, // 无数据 Move(i32, i32), // 元组 Write(String), // 单个值 ChangeColor(i32, i32, i32), // RGB }3. 枚举 + match 是 Rust 核心模式
match必须穷尽所有变体,不会遗漏- 常用
_通配其他情况
match msg { Message::Quit => println!("退出"), _ => (), }4. Option 枚举
Rust 内置,用来表示可能为空,替代 null:
enum Option<T> { Some(T), None, }- 有值用
Some(value) - 无值用
None - 必须显式处理空值,安全可靠
5. if let 简化匹配
只关心某一种变体时,用if let更简洁:
if let Some(x) = opt_val { println!("{}", x); }6. 枚举可以定义方法
用impl给枚举写方法,和结构体一样:
impl Message { fn call(&self) { ... } }一句话核心记忆
Rust 枚举 = 可带数据的标签 + 安全的模式匹配 + 内置 Option 处理空值,是 Rust 处理多类型、多状态、可选值的核心工具。
5.数组
1. 基本特点
- 固定长度、固定类型,长度不可变
- 数据在栈上存储,访问快
- 语法:
[类型; 长度]
let arr: [i32; 5] = [1, 2, 3, 4, 5];2. 快速初始化
- 初始化为相同值:
let arr = [0; 5]; // [0,0,0,0,0]3. 访问元素
- 下标从 0 开始:
arr[0] - 越界访问会直接 panic(运行时错误)
4. 常用操作
- 获取长度:
arr.len() - 切片:
&arr[1..3] - 遍历:
for n in arr或for n in &arr
5. 适用场景
- 已知长度、数量固定的一组数据
- 追求栈上高效存储
6. 与 Vec 区别
- 数组:长度固定,栈上
- Vec:长度可变,堆上
一句话记忆:Rust 数组是固定长度、栈存储、快速访问的同类型集合,越界会崩溃。