Skip to content

堆上的向量

我们将要介绍的第一个集合类型是 Vec<T>, ,也称为向量。向量允许您在单个数据结构中存储多个值,该数据结构将所有值并排放置在内存中。向量只能存储相同类型的值。当您有项目列表时,它们很有用,例如文件中的文本行或购物车中项目的价格。

Vec<T> 包含在 标准库前奏中, 这意味着无需手动导入它。

创建新向量

为了创建一个新的空向量,我们调用该 Vec::new 函数,如下所示:

sway
    let v: Vec<u64> = Vec::new();

请注意,我们在此处添加了类型注释。由于我们没有向此向量插入任何值,因此 Sway 编译器不知道我们打算存储哪种元素。向量是使用泛型实现的,这意味着 Vec<T> 标准库提供的类型可以容纳任何类型。当我们创建向量来容纳特定类型时,我们可以在尖括号内指定类型。在上面的示例中,我们告诉 Sway 编译器 Vec<T>v 容纳该 u64 类型的元素。

更新向量

要创建一个向量,然后向其中添加元素,我们可以使用方法 push ,如下所示:

sway
    let mut v = Vec::new();

    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);

与任何变量一样,如果我们想要更改其值,则需要使用关键字使其可变,如声明变量 mut 部分所述。我们放入其中的数字都是类型,Sway 编译器会根据数据推断出这一点,因此我们不需要注释。 u64 Vec<u64>

读取向量元素

要读取存储在向量中特定索引的值,可以使用 get 如下所示的方法:

sway
    let third = v.get(2);
    match third {
        Some(third) => log(third),
        None => revert(42),
    }

请注意这里的两个细节。首先,我们使用的索引值 2 来获取第三个元素,因为向量是按数字索引的,从零开始。其次,我们使用将 get 索引作为参数传递的方法来获取第三个元素,这给了我们一个 Option<T>

get 方法传递一个向量之外的索引时,它会返回 None 而不会崩溃。如果在正常情况下偶尔会访问向量范围之外的元素,这尤其有用。然后,您的代码将具有处理 或 Some(element) 的逻辑 None。例如,索引可以作为契约方法参数。如果传递的参数太大,则该方法 get 将返回一个 None 值,然后契约方法可能会决定在发生这种情况时恢复或返回一个有意义的错误,告诉用户当前向量中有多少个项目并让他们有另一次机会传递有效值。

迭代向量中的值

为了依次访问向量中的每个元素,我们将使用循环 whilelen 方法遍历所有有效索引,如下所示:

sway
    let mut i = 0;
    while i < v.len() {
        log(v.get(i).unwrap());
        i += 1;
    }

这里需要注意两个细节。首先,我们使用 len 方法返回向量的长度。其次,我们调用 unwrap 方法来提取 Option 返回的 get。我们知道 unwrap 不会失败(即不会导致恢复),因为传递给 get的每个索引'i 都已知小于向量的长度。

使用枚举储存多种类型

向量只能存储相同类型的值。这可能很不方便;肯定有需要存储不同类型的项目列表的用例。幸运的是,枚举的变体定义在相同的枚举类型下,因此当我们需要一种类型来表示不同类型的元素时,我们可以定义和使用枚举!

例如,假设我们想要从表中的一行中获取值,其中行中的一些列包含整数、一些 b256 值和一些布尔值。我们可以定义一个枚举,其变体将保存不同的值类型,并且所有枚举变体将被视为同一类型:枚举的类型。然后我们可以创建一个向量来保存该枚举,因此最终可以保存不同的类型。我们在下面演示了这一点:

sway
    enum TableCell {
        Int: u64,
        B256: b256,
        Boolean: bool,
    }

    let mut row = Vec::new();
    row.push(TableCell::Int(3));
    row.push(TableCell::B256(0x0101010101010101010101010101010101010101010101010101010101010101));
    row.push(TableCell::Boolean(true));

现在我们已经讨论了一些最常见的使用向量的方法,请务必查看 Vec<T> 标准库中定义的所有有用方法的 API 文档。目前,这些方法可以在的 源代码 Vec<T>中找到。例如,除了 push, 还有一种 pop 方法可以移除并返回最后一个元素,一种 remove 方法可以移除并返回向量中某个选定索引处的元素,一种 insert 方法可以在向量中某个选定索引处插入元素,等等。