Skip to content

第六节、切片

切片

切片允许您引用集合中的连续元素序列,而不是整个集合。切片是一种引用,因此它没有所有权。

例如字符串切片:

    let s = String::from("hello world");

    let hello = &s[0..5];
    let world = &s[6..11];

2601644915006_.pic.jpg

变量hello,和变量world是字符串s的切片。 稍微数一下你发现切片的第一个数字是包含在切片里面的,例如:0,6 切片的结束数字是不饱和的例如:5,11。

例子中 5是空格" ",这两个变量都没有包含它。

第一个数字可以不写,下面两个切片是等效的

let s = String::from("hello");

let slice = &s[0..2];
let slice = &s[..2];

最后一个也可以不写,也是等效的

let s = String::from("hello");

let len = s.len();

let slice = &s[3..len];
let slice = &s[3..];

所以还可以这样写

let s = String::from("hello");

let len = s.len();

let slice = &s[0..len];
let slice = &s[..];

了解以上特性,写一个函数来获取第一个单词

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

    let word = first_word(&s);

    println!("the first word is: {}", word);
}
fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();
    //这段语法是后面的内容,枚举返回hello,world的单个字节和位置。
    //这个内容不需要在此章节理解
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i]; //只有这个切片属于本章节内容
        }
    }

    &s[..]
}

复习一下前面的内容

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

    let word = first_word(&s);

    s.clear(); // error! 这个地方会报错

    println!("the first word is: {}", word);
}
报错的原因是 切片是引用,所有权归属元字符串。

word 这个切片是不可变引用, 后面还打印了word,这时候s.clear是可变操作,所以发生了冲突。

可以把s.clear()放在打印之后操作。