切片
切片是 Rust 中提供的一种不持有所有权的数据类型,它是对某些类型(String,Array...)特定位置的引用。
- 在 Rust 中,字符串的字面值就是切片类型,是对二进制程序特定位置值的一个引用,并且是不可变引用
- 切片类型的符号使用 &str 表示
接下来我们看一下如何创建一个切片
// 1.使用字面值创建切片
let slice = "haha";
// 2.使用 range 对 String 进行切片
let s = String::from("hello world");
let sclice_s = &s[0..5]; // "hello"
// 如果是从开头到结尾进行切片,则可以简写
let sclice_s_all = &s[..]; // "hello world"
为什么要使用切片
对于初学的同学可能会有这样一个疑问,为什么要使用切片,使用切片是为了解决什么问题?要搞明白这些问题,我们首先应该了解一些应用场景,才能有助于后续的分析。假设现在我们要设计这样一个函数,其功能是提取一个字符串中首个空格前的所有字符,没有空格则返回整个字符串,如("hello world" 提取出 "hello"),但现在我们不能使用切片,只能考虑获取关键位置的索引
- 从一个字符串中匹配第一个出现的空格,并返回其索引
- 如果没有匹配到空格,则返回字符串的长度
接下来我们看 Rust 的实现
fn main() {
let str = String::from("hello world");
let index = get_space_index(&str);
println!("index is {}", index); // index is 5
}
fn get_space_index(s: &String) -> usize {
// 将字符串转为字符数组
let arr = s.as_bytes();
for (i, &item) in arr.iter().enumerate() {
if item == b' ' {
return i;
}
}
s.len()
}
上面的例子可以实现获取首个空格的索引,后续我们也可以通过这个索引来实现需求,但这种方式的问题是,我们获取的索引和字符串不是强关联的,如果我们在使用索引之前,意外的对目标字符串进行了修改,那么这个索引也就失去它的意义了。
基于以上的问题,我们应该使用切片来建立与目标字符串的强关联,并且利用切片是不可变引用的特性,让 Rust 编译器来帮我们检查 通过可变引用修改目标字符串值 的不合理操作 (对于这里有疑问的同学可以看我的上一篇分享 -《03-引用与借用》)
接下来我们使用切片来实现最初的需求
fn main() {
let str = String::from("hello world");
let first_word = slice_first_word(&str[..]);
println!("{}", first_word); // hello
}
fn slice_first_word(s: &str) -> &str {
// 将字符串转为字符数组
let arr = s.as_bytes();
for (i, &item) in arr.iter().enumerate() {
// 判断当前位是否是空格
if item == b' ' {
return &s[..i];
}
}
&s[..]
}
其他数据类型的切片
数组
let arr = [1,2,3,4,5];
let slice = &arr[1..3];
println!("{:?}", slice); // [2,3]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。