开发环境
- Windows 10
- Rust 1.56.0
- VS Code 1.61.2
项目工程
这里继续沿用上次工程rust-demo
切片类型
另一个没有所有权的数据类型是切片。切片允许您引用集合中的连续元素序列,而不是整个集合。
下面是一个小的编程问题:编写一个函数,该函数接受一个字符串并返回它在该字符串中找到的第一个单词。如果函数在字符串中找不到空格,则整个字符串必须是一个单词,因此应该返回整个字符串。
首先我们考虑一下这个函数:
fn first_word(s: &String) -> ?
这个函数first_word有一个&String作为参数。我们不想要所有权,所以这没问题。但我们应该返回什么呢?我们没有办法谈论字符串的一部分。但是,我们可以返回单词末尾的索引。可以看下面的代码:
fn first_word(s: &String) -> usize {
let bytes = s.as_bytes(); // 将字符串转换成一个字节数组,以便下面逐个遍历
for (i, &item) in bytes.iter().enumerate() { // 使用iter()方法在字节数组上创建一个迭代器
if item == b' ' {
return i; // 返回字符的索引
}
}
s.len()
}
现在,iter()是一个方法,它返回集合中的每个元素,enumerate()枚举封装iter()的结果,然后将每个元素作为元组的一部分返回。enumerate()枚举返回的元组的第一个元素是索引,第二个元素是对元素的引用。这比自己计算索引要方便一些。
因为enumerate()枚举方法返回一个元组,所以我们可以使用模式来重构该元组。因此,在for循环中,我们指定了一个模式,它在元组中为索引指定了i,对于元组中的单个字节指定了&Item。因为我们从.iter().enumerate()获得了对元素的引用,所以我们在模式中使用