实战总结
> 综合运用切片知识,通过实战示例巩固切片的用法,识别常见错误与调试技巧。
常见错误
错误 1:无效的切片范围
rust
▶ Runfn main() {
let s = String::from("hello");
// ❌ 超出范围
// let slice = &s[10..15];
// ✅ 正确
if s.len() >= 5 {
let slice = &s[0..5];
println!("{}", slice);
}
}错误信息:
thread 'main' panicked at 'range end index 15 out of range for slice of length 5'错误 2:UTF-8 边界问题
rust
▶ Runfn main() {
let s = String::from("你好");
// ❌ 破坏字符编码
// let bad = &s[0..1]; // panic!
// ✅ 使用字符迭代
for c in s.chars() {
println!("{}", c);
}
// ✅ 使用 get 检查
match s.get(0..1) {
Some(slice) => println!("{}", slice),
None => println!("无效的字符边界"),
}
}错误信息:
thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside '你' (bytes 0..3) of `你好`'错误 3:类型混淆
rust
▶ Runfn main() {
let s1 = String::from("hello");
// ❌ 错误:类型不匹配
// let s2: String = &s1;
// ✅ 正确
let s2: &str = &s1;
let s3: String = s1.clone();
}错误 4:切片所有权
rust
▶ Runfn main() {
let s = String::from("hello");
let slice = &s[..];
// ❌ 错误:返回局部变量的切片
// fn get_slice() -> &str {
// let s = String::from("hello");
// &s[..] // s 在函数结束时被释放
// }
// ✅ 正确:返回 String
fn get_string() -> String {
String::from("hello")
}
}调试技巧
打印切片信息
rust
▶ Runfn main() {
let s = String::from("hello world");
let slice = &s[0..5];
println!("原字符串:'{}'", s);
println!("切片:'{}'", slice);
println!("切片长度:{}", slice.len());
println!("切片字节:{:?}", slice.as_bytes());
}检查边界
rust
▶ Runfn safe_slice(s: &str, start: usize, end: usize) -> Option<&str> {
if start > end {
println!("错误:start > end");
return None;
}
if end > s.len() {
println!("错误:end > 字符串长度");
return None;
}
if !s.is_char_boundary(start) || !s.is_char_boundary(end) {
println!("错误:无效的字符边界");
return None;
}
Some(&s[start..end])
}
fn main() {
let s = "你好世界";
match safe_slice(s, 0, 3) {
Some(slice) => println!("切片:{}", slice),
None => println!("切片失败"),
}
}练习
练习 1:最后一个单词
编写函数,返回字符串的最后一个单词。
rust
▶ Runfn last_word(s: &str) -> &str {
// 你的代码
}练习 2:统计大写字母
编写函数,统计字符串中大写字母的数量。
rust
▶ Runfn count_uppercase(s: &str) -> usize {
// 你的代码
}练习 3:字符串压缩
实现 Run-Length 编码:"aaabbcccc" → "a3b2c4"
小结
切片要点
| 概念 | 说明 |
|---|---|
| 切片类型 | &[T](数组切片),&str(字符串切片) |
| 所有权 | 不拥有数据,只是引用 |
| 大小 | 运行时确定(胖指针:指针 + 长度) |
| 安全性 | 有边界检查,UTF-8 检查 |
&str vs String
| 特性 | &str | String |
|---|---|---|
| 所有权 | 借用 | 拥有 |
| 可变性 | 不可变 | 可变 |
| 大小 | 16 字节 | 24 字节 |
| 用途 | 函数参数、只读 | 需要修改时 |
最佳实践
- 函数参数优先使用&str(更灵活)
- 切片有边界检查(安全但可能 panic)
- 注意 UTF-8 字符边界(特别是中文)
- 使用
get方法安全访问(返回 Option)
关键要点
- 切片是对数据集合的引用,不复制数据
- &str 是 Rust 中最常用的字符串类型
- 切片操作安全,但有运行时检查
- 理解 String 和&str 的区别和转换
练习题
详见:练习题