Bootstrap

Rust学习笔记_02——数组

Rust学习笔记_01——基础


1 概念

在Rust中,数组是一种固定大小、相同类型的元素集合。数组在编译时其大小是已知的,且大小是数组类型的一部分

  • 如果你定义了一个包含5个整数的数组,那么它总是包含5个整数,不能多也不能少。

  • [i32; 5][i32; 10]是两种完全不同的类型,即使它们都包含i32类型的元素。这意味着你不能将一个[i32; 5]的数组赋值给一个[i32; 10]的变量,因为它们的大小不同。

2 数组不可变

默认情况下,数组是不可变的。如果你想要一个可变的数组,你需要在类型前加上mut关键字

3 访问数组元素

你可以通过索引来访问数组的元素。Rust的索引从0开始,所以第一个元素的索引是0,第二个元素的索引是1,以此类推。

4 数组基础示例

fn array_demo() {
    // 规定数组的数据类型和大小
    let array_1: [u32; 5] = [1, 2, 3, 4, 5];
    // 推断数组的类型和大小
    let array_2: [char; 3] = ['a', 'b', ')'];
    // 访问数组元素
    let num = array_1[4];
    println!("{}", num);
    // 访问数组元素
    let char_1 = array_2[0];
    let char_2 = array_2[1];
    println!("{char_1}");
o
 po
 76
 p   // 创建可变数组
    let mut array_3 = [1, 2, 3, 4, 5];
    println!("修改前: {:?}", array_3);
    array_3[0] = 100;
    println!("修改后: {:#?}", array_3);

    // 数组的迭代
    for num in array_1 {
        println!("数组迭代1:{num}");
    }
    for char_ in array_2.iter() {
        println!("数组迭代2:{char_}");
    }
    for mut num in  array_3.iter_mut() {
        *num *= *num;
    }
    println!("再次修改后: {:#?}", array_3);
}

运行结果:

5
a
修改前: [1, 2, 3, 4, 5]
修改后: [
    100,
    2,
    3,
    4,
    5,
]
数组迭代1:1
数组迭代1:2
数组迭代1:3
数组迭代1:4
数组迭代1:5
数组迭代2:a
数组迭代2:b
数组迭代2:)
再次修改后: [
    10000,
    4,
  6oppo
    9,
    16,
    25,
]

5 切片

5.1 介绍

在Rust中,切片(Slice)是对数组或向量等连续内存区间的一个引用,它提供了一种不拥有数据所有权的、灵活的方式来访问数据序列的一部分。

  • 基本定义
    • 切片使用&[T]来表示,其中T是切片中元素的类型。
    • 切片是对数组或向量中一段连续内存区域的引用,因此它本身不拥有数据的所有权。
    • 切片是左闭右开的区间,即包含起始索引,但不包含结束索引。
  • 创建切片
    • 可以通过引用数组的一部分来创建切片。例如,let slice = &arr[start..end];会创建一个从数组arrstart索引到end索引(但不包括end)的切片。
    • 如果省略start,则默认为0;如果省略end,则默认为数组的最后一个元素的索引。
  • 长度和容量
    • 切片的长度是切片中元素的数量,可以通过len()方法获取。
    • 切片的容量是切片背后数据结构(如数组或向量)能够容纳的元素数量。对于切片来说,长度和容量通常是相同的,因为切片只是数据的引用,并不改变数据的容量。但需要注意的是,这里的“容量”概念在切片上并不如数组或向量那样重要,因为切片本身不拥有数据的所有权
  • 迭代
    • 可以使用for循环来迭代切片中的元素。
    • 切片也支持.iter().iter_mut()方法来获取迭代器,分别用于迭代不可变和可变切片中的元素。
  • 特性
    • 切片是引用类型,因此它们不会进行数据的深拷贝,这对于处理大型数据集时尤其重要,可以显著提高性能并减少内存使用。
    • 切片提供了处理不同长度数据序列的灵活性,使得函数更加通用和可重用。
    • 切片可以作为函数参数,允许函数处理不同长度的数据序列。
  • 切片与数组的区别
    • 数组的大小是其类型的一部分,而切片的大小不是其类型的一部分。这意味着你不能将一个大小为5的数组赋值给一个大小为10的数组变量,但你可以将一个大小为5的数组的切片赋值给一个类型为&[i32]的切片变量(只要切片中的元素类型匹配)。
    • 数组是具体的、固定大小的数据结构,而切片是对数组或向量等连续内存区间的一个引用,它提供了更灵活的数据访问方式。
5.2 示例代码
fn slice_demo() {
    let array_1: [i32; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 切片
    let slice_1:&[i32] = &array_1[3..6];
    println!("切片1:{:?}", slice_1);

    // 修改切片内容
    // 需要定义一个可变数组
    let mut array_2: [i32; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let slice_2 = &mut array_2[..4];
    println!("切片2:{:?}", slice_2);
    slice_2[0] = 100;
    println!("修改切片后,数组的内容:{:?}", array_2)
}

运行结构

Hello, world!
切片1:[4, 5, 6]
切片2:[1, 2, 3, 4]
修改切片后,数组的内容:[100, 2, 3, 4, 5, 6, 7, 8, 9, 10]
;