切片
- rust的另外一种不持有所有权的数据类型:切片(slice)
- 一道题,编写一个函数:
- 它接收字符串作为参数
- 返回它在这个字符串里找到的第一个单词
- 如果函数找不到任何空格,那么整个字符串就被返回
fn main(){
let mut s = String::from("hello world");
let wordIndex = first_world(&s);
// 删除String s 使其失效
// 获取的wordIndex 不能在通过该支取获取后面的字符串
s.clear();
println!("wordIndex:{}", wordIndex);
}
fn first_world(s: &String)-> usize{
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate(){
if item == b' '{
return i;
}
}
s.len()
}
fn main(){
let mut s = String::from("hello world"); // 可变引用
let str = first_world(&s); // s 作为不可变引用传入方法中
// 编译报错,不能同时拥有可变引用和不可变引用
// s.clear();
println!("str:{}", str);
}
fn first_world(s: &String)-> &str{
let bytes = s.as_bytes();
for(i, &item) in bytes.iter().enumerate(){
if item == b' '{
return &s[..i];
}
}
&s[..]
}
字符串切片
- 字符串切片是指向字符串一部分内容的引用
- 形式:[开始索引…结束索引]
- 开始索引就是切片起始位置的索引值
- 结束索引是切片终止位置的下一个索引值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iUmhF91T-1664259671687)(./qiepian.png)]
fn main(){
let s = String::from("hello world");
// 写法1
// let hello = &s[0..5];
// let world = &s[6..11];
// 写法2
let hello = &s[..5];
let world = &s[6..s.len()];
let whole = &s[..];
println!("hello:{}, world:{}, whole:{}", hello, world, whole);
}
注意
- 字符串切片的范围索引必须发生在有效的UTF-8字符边界内。
- 如果尝试从一个多字节的字符中创建字符串切片,程序会报错并退出
字符串字面值是切片
- 字符串字面值被直接存储在二进制程序中
// 类型是 &str 切片
let s = "hello world";
- 变量s的类型是&str,它是一个执行二进制程序特定位置的切片
- &str是不可变引用,所以字符串字面值也是不可变得
将字符串切片作为参数传递
- fn first_world(s: &String)-> &str{}
有经验的rust开发者会采用&str作为参数类型,因为这样就可以同时接收String和&str类型的参数了 - fn first_world(s: &str)-> &str{}
- 使用字符串切片,直接调用该函数
- 使用String,可以创建一个完整的String切片来调用改函数
- 定义函数时使用字符串切片来代替字符串引用会使我们的API更加通用,且不会损失任何功能
fn main(){
let str_1 = String::from("hello world");
let res_1 = first_world(&str_1);
let str_2 = "hello world";
let res_2 = first_world(str_2);
println!("rest_1:{}", res_1);
println!("rest_2:{}", res_2);
}
fn first_world(s: &str)-> &str{
let bytes = s.as_bytes();
for(i, &item)in bytes.iter().enumerate(){
if item == b' '{
return &s[..i];
}
}
&s[..]
}
其他类型的切片
fn main(){
// 类型[i32; 4]
let a = [3, 4, 5, 6];
// 类型 &[i32]
let slice = &a[1..=3];
println!("slice:{:?}", slice);
}