Rust Slice(切片)类型


Rust中的Slice(切片)

Rust的 slice 类型是一个类似于数组的序列类型,但是它不直接拥有数据,仅仅是一种引用数据的方式。 slice 可以引用任何连续的一段序列,不管是位于堆上还是栈上的数据。 Slice 是一个相对较小的类型,由于它没有拥有数据,所以本身是一个轻量级的指针类型。

在 Rust 中,Slice 被广泛应用于函数参数,以及其它数据结构,如字符串,文件数据等等。使用 Slice 类型可以极大地提升代码的灵活性和高效性。

创建 Slice

Slice 可以通过两种方式创建,一种是使用 [start..end] 的区间语法,另一种是使用 &arr[index..end] 来引用数组或者数据结构中的一段连续的数据。其中, start 值表示的是起始位置的的下标, end 表示的是结束位置的下标,但 end 本身不包含在 Slice 内部。也就是说,如果 Slice 包含了 [0, 2, 4, 6, 8] 这个序列,那么写法应该是 &arr[0..5]。在这个例子中, start 为 0, end 为 5。

作为函数参数

Slice 的最常见的应用场景就是函数的参数类型。在 Rust中, Slice 可以作为函数的参数来传递需要处理的数据序列。Slice 可以避免在传参时发生数据复制的操作,因此相比较值传递,效率会更高。

fn find_max(arr: &[i32]) -> i32 {
    let mut max = 0;
    for &x in arr.iter() {
        if x > max {
            max = x;
        }
    }
    max
}

fn main() {
    let v = vec![1, 2, 3, 4, 5];
    let arr = &v[..];
    
    println!("{}", find_max(arr));
}

在上面的这个例子中,我们将一个 Vec<i32> 的参数作为一个 Slice<i32> 传递到了 find_max 函数中。在函数内部,函数会计算出这个序列中最大的值并返回。在最后我们通过传递 Slice 变量 arr 调用了函数,并将结果打印出来。注意,虽然 find_max 函数中修改的 max 变量是引用类型,但是并不需要使用可变引用。

处理字符串

另一个常见的应用场景就是处理字符串。slice 可以用来截取任何字符串的一个子串,然后可以对子串进行操作。我们可以通过两种方式来定义一个 string slice,一种是明确定义一个 string,然后创建一个 slice。另外一种是直接从一个变量直接显式地创建一个slice。这两种方式的创建分别为:

let s = String::from("hello world");
let hello = &s[..5];
let world = &s[6..];

let my_string = String::from("hello world");
let word = first_word(&my_string);

需要注意的一点是,Rust 并不会在原字符串中插入分隔符,因为它会在某个操作需要使用到的时候做出裁剪。举个例子,在上面的第一个代码块中我们使用 &s[6..] 得到的结果中,并不包含分隔符 ' ',所以它会被输出出来。

最后,值得一提的是,Slice 是一个简单、高效的类型,在 Rust 中非常常见。熟练掌握 Slice 的应用,可以大大提高代码的效率和代码的灵活性。