Rust入门系列之切片

切片

切片是 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]

你可能感兴趣的:(rust前端)