rust学习笔记-所有权三之切片

除了引用,Rust 还有另外一种不持有所有权的数据类型:切片(slice)。切片允许我们引用集合中某一段连续的元素序列,而不是整个集合。
例如代码

1
2
3
4
5
6
7
8
9
fn main() {
let mut s = String::from("hello world");

let word = first_word(&s);

s.clear();

// 这时候虽然 word 还是 5,但是 s 已经被清除了,所以就没存在的意义
}

这里其实我们就需要关注 s 的存在性,代码的逻辑合理性就需要额外去维护,此时我们就可以用切片

1
2
3
4
let s = String::from("hello world")

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

其实跟 Python 的list 之类的语法有点类似,当然里面还有些语法糖,比如可以直接用省略后面的数字表示直接引用到结尾

1
let hello = &s[0..];

甚至再进一步

1
let hello = &s[..];

使用了切片之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();

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);
}

那再执行 main 函数的时候就会抛错,因为 word 还是个切片,需要保证 s 的有效性,并且其实我们可以将函数申明成

1
fn first_word(s: &str) -> &str {

这样就既能处理&String 的情况,就是当成完整字符串的切片,也能处理普通的切片。
其他类型的切片

1
2
let a = [1, 2, 3, 4, 5];
let slice = &a[1..3];

简单记录下,具体可以去看看这本书