Rust-- Vec, Array and Slice

540 阅读3分钟

如果想在rust中存储一组值,有 vector和 array 两种选择

Creating a vector 创建 vector

本文介绍三种创建 vector 的方式

使用new创建并插入元素

fn main() {
    // vector 还拥有 len 和 capacity两个属性
    // len表示目前存储有多少个元素
    // capacity表示,不再新分配容量的前提下,目前能存储多少元素
    let mut values: Vec<u32> = Vec::new();
    values.push(1);

    println!("{}", values.len());
    println!("{}", values.capacity());
}

输出:
1
4




fn main() {
    // vector 还拥有 length 和 capacity两个属性
    let mut values: Vec<u32> = Vec::new();
    values.push(1);
    values.push(2);
    values.push(3);
    values.push(4);
    values.push(5);

    println!("{}", values.len());
    println!("{}", values.capacity());
}

输出:
5
8

如果我们再增加4个元素,就超过了capacity 8, 则会新分配存储空间,使得capacity继续增大到16

Removing values from a vector 从vector中删除值

有两种删除方式,一种是pop, 一种是remove

// 使用 pop 删除最后一个元素
fn main() {
    // vector 还拥有 length 和 capacity两个属性
    let mut values: Vec<u32> = Vec::new();
    values.push(1);
    values.push(2);
    values.push(3);
    values.push(4);
    values.push(5);

    println!("len before: {}", values.len());
    println!("capacity before: {}", values.capacity());

    values.pop(); // 删除掉最后加入的元素,即5
    println!("len after: {}", values.len());
    println!("capacity after: {}", values.capacity());
}


len before: 5
capacity before: 8
len after: 4
capacity after: 8

// 使用 remove 删除指定位置的元素

fn main() {
    // vector 还拥有 length 和 capacity两个属性
    let mut values: Vec<u32> = Vec::new();
    values.push(1);
    values.push(2);
    values.push(3);
    values.push(4);
    values.push(5);

    println!("len before: {}", values.len());
    println!("capacity before: {}", values.capacity());

    values.pop();
    values.remove(0); // 删除第一个元素,如果越界,会出现运行时错误 panick
    println!("len after: {}", values.len());
    println!("capacity after: {}", values.capacity());
    println!("first value is {}", values[0]); // 可以读取指定位置的元素
}


len before: 5
capacity before: 8
len after: 3
capacity after: 8
first value is 2

使用 vec! macro 来创建

fn main() {
    // vector 还拥有 length 和 capacity两个属性
    let mut values: Vec<u32> = vec![1, 2, 3, 4, 5];

    println!("len before: {}", values.len());
    println!("capacity before: {}", values.capacity());

    values.pop();
    println!("len after: {}", values.len());
    println!("capacity after: {}", values.capacity());
    println!("first value is {}", values[0]);
}

len before: 5
capacity before: 5  // 此处的capacity为5
len after: 4
capacity after: 5
first value is 1

使用 with_capacity 创建

fn main() {
    // 创建容量为5的vector,并插入5个元素
    // 如果插入的元素超过容量,则会触发重新分配空间,使得能容纳更多元素
    let mut values: Vec<u32> = Vec::with_capacity(5);
    values.push(1);
    values.push(2);
    values.push(3);
    values.push(4);
    values.push(5);
    println!("len before: {}", values.len());
    println!("capacity before: {}", values.capacity());

    values.pop();
    println!("len after: {}", values.len());
    println!("capacity after: {}", values.capacity());
    println!("first value is {}", values[0]);
}

len before: 5
capacity before: 5
len after: 4
capacity after: 5
first value is 1

Creating an array 创建 array

与vector不同之处在于, array拥有固定的大小, 即创建时你就得知道大小。固定大小也意味着,不能像vec那样,在创建之后增加/删除元素。

fn main() {
    // array的类型写作: [元素类型; size]
    let array: [u32; 3] = [1, 2];
}

大小不匹配,编译报错:
error[E0308]: mismatched types
 --> src/main.rs:3:27
  |
3 |     let array: [u32; 3] = [1, 2];
  |                --------   ^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements


// 可以通过index来访问某个位置的元素

fn main() {
    // array的类型写作: [元素类型; size]
    let array: [u32; 3] = [1, 2, 3];

    println!("first value: {}", array[0]);
}

first value: 1

Slices

使用函数时,当我们不想将vector 或 array 的ownership进行move时,可以考虑用reference, 如果不想具体指明到底是对vector,还是对array的reference,就 可以使用slice。

slice看起来跟array的声明很像,只是不需要指定size,下例中,我们创建一个函数use_slice,用slice作为它的参数类型. 在main函数中调用use_slice时,只需将已定义的array或vector的reference传入,随后rust会自动将其强制转换为slice类型


fn use_slice(slice: &[u32]) {
    println!("first value is {}", slice[0]);
}

fn main() {
    // array的类型写作: [元素类型; size]
    let array: [u32; 3] = [1, 2, 3];
    let values = vec![10, 9, 8, 7];

    use_slice(&array);
    use_slice(&values);
}

first value is 1
first value is 10

参考

[1] www.youtube.com/watch?v=wDX…