9、初识Rust – slice类型
目录 编程
slice允许开发者使用集合中一段连续的元素序列,而不用引用整个集合。slice是一类引用,所以它没有所有权。
理解slice之前,我们先来尝试实现一个功能,提取字符串中某字符开始后的指定内容。
fn main() { let a = String::from("hello,world"); for (i,&item) in a.as_bytes().into_iter().enumerate() { println!("{item}"); } }
如上,声明一个变量a,并附值hello,world。
然后将a转换为字节数组,并使用 iter 创建一个迭代器。iter方法会返回集合中每一个元素,在使用enumerate包装返回的结果,然后将结果进行for遍历。
遍历索引会存放在i变量,内容会存放在 item变量。
fn main() { let a = String::from("hello,world"); let b = test_function(&a); println!("{b}"); } fn test_function(a: &String) -> usize { for (i, &item) in a.as_bytes().iter().enumerate() { if item == b',' { return i; }; }; a.len() }
然后对item进行一个判断,遇到字符串 ( , ) 时,返回该字符串所在的位置,如果没有找到,那么就返回字符串长度。如上代码,返回 5。接下去就可以使用slice方法提取该字符后指定数量的字符串。
fn main() { let a = String::from("hello,world"); let b = test_function(&a); let c = &a[b..{b + 2}]; println!("{c}"); } fn test_function(a: &String) -> usize { for (i, &item) in a.as_bytes().iter().enumerate() { if item == b',' { println!("{item},{i}"); return i; }; }; a.len() }
为什么上面没有看见slice关键字?因为slice已内置在字符串变量中,所以直接简写即可。
let a = String::from("hello,world"); let b = &a[..2]; //let b = &a[0..2]; let c = &a[2..]; //let b = &a[2..{a.len()}];
也可以像上面这样写。但是需要注意,长度如果超出字符串,则会抛出错误,所以在使用时,需要注意判断。
注意:字符串 slice range 的索引必须位于有效的 UTF-8 字符边界内,如果尝试从一个多字节字符的中间位置创建字符串 slice,则程序将会因错误而退出。出于介绍字符串 slice 的目的,本部分假设只使用 ASCII 字符集;第八章的 “使用字符串存储 UTF-8 编码的文本” 部分会更加全面的讨论 UTF-8 处理问题。