Skip to content

实战总结

> 综合运用切片知识,通过实战示例巩固切片的用法,识别常见错误与调试技巧。

常见错误

错误 1:无效的切片范围

rust
fn main() {
    let s = String::from("hello");

    // ❌ 超出范围
    // let slice = &s[10..15];

    // ✅ 正确
    if s.len() >= 5 {
        let slice = &s[0..5];
        println!("{}", slice);
    }
}
▶ Run

错误信息:

thread 'main' panicked at 'range end index 15 out of range for slice of length 5'

错误 2:UTF-8 边界问题

rust
fn 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!("无效的字符边界"),
    }
}
▶ Run

错误信息:

thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside '你' (bytes 0..3) of `你好`'

错误 3:类型混淆

rust
fn main() {
    let s1 = String::from("hello");

    // ❌ 错误:类型不匹配
    // let s2: String = &s1;

    // ✅ 正确
    let s2: &str = &s1;
    let s3: String = s1.clone();
}
▶ Run

错误 4:切片所有权

rust
fn 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")
    }
}
▶ Run

调试技巧

打印切片信息

rust
fn main() {
    let s = String::from("hello world");
    let slice = &s[0..5];

    println!("原字符串:'{}'", s);
    println!("切片:'{}'", slice);
    println!("切片长度:{}", slice.len());
    println!("切片字节:{:?}", slice.as_bytes());
}
▶ Run

检查边界

rust
fn 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!("切片失败"),
    }
}
▶ Run

练习

练习 1:最后一个单词

编写函数,返回字符串的最后一个单词。

rust
fn last_word(s: &str) -> &str {
    // 你的代码
}
▶ Run

练习 2:统计大写字母

编写函数,统计字符串中大写字母的数量。

rust
fn count_uppercase(s: &str) -> usize {
    // 你的代码
}
▶ Run

练习 3:字符串压缩

实现 Run-Length 编码:"aaabbcccc""a3b2c4"


小结

切片要点

概念说明
切片类型&[T](数组切片),&str(字符串切片)
所有权不拥有数据,只是引用
大小运行时确定(胖指针:指针 + 长度)
安全性有边界检查,UTF-8 检查

&str vs String

特性&strString
所有权借用拥有
可变性不可变可变
大小16 字节24 字节
用途函数参数、只读需要修改时

最佳实践

  1. 函数参数优先使用&str(更灵活)
  2. 切片有边界检查(安全但可能 panic)
  3. 注意 UTF-8 字符边界(特别是中文)
  4. 使用 get 方法安全访问(返回 Option)

关键要点

  • 切片是对数据集合的引用,不复制数据
  • &str 是 Rust 中最常用的字符串类型
  • 切片操作安全,但有运行时检查
  • 理解 String 和&str 的区别和转换

练习题

详见:练习题