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[..]; // 整个字符串 &str
4. 重要规则
-
切片索引按
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 数组是固定长度、栈存储、快速访问的同类型集合,越界会崩溃。