Icon Link向量

我们将首先看一下 Vec<T>,也称为向量的集合类型。向量允许您在单个数据结构中存储多个值,将所有值都放在内存中的相邻位置。向量只能存储相同类型的值。当您有一个项目列表时,例如文件中的文本行或购物车中商品的价格时,它们非常有用。

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

Icon Link创建一个新的向量

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

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

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

Icon Link更新一个向量

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

let mut v = Vec::new();
 
v.push(5);
v.push(6);
v.push(7);
v.push(8);

与任何变量一样,如果我们希望能够更改其值,我们需要使用 mut 关键字使其可变,如 声明一个变量 部分所讨论的。我们放置在其中的数字都是 u64 类型,Sway 编译器从数据中推断出这一点,因此我们不需要 Vec<u64> 注释。

Icon Link读取向量的元素

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

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 值,然后合同方法可能决定在发生这种情况时恢复,或者返回一个有意义的错误,告诉用户当前向量中有多少项,并给他们另一个机会传递有效的值。

Icon Link遍历向量中的值

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

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

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

Icon Link使用枚举存储多种类型

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

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

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 文档。目前,这些可以在 source code for Vec<T> Icon Link 中找到。例如,除了 push 之外,pop 方法会移除并返回最后一个元素,remove 方法会移除并返回向量中某个选择的索引处的元素,insert 方法会在向量中的某个选择的索引处插入元素等。