集合
集合类型是任何编程语言的基础部分。它们用于存储数据集合,例如项目列表。vector
类型已经在
向量部分 中介绍过,本章我们将介绍 Sui 框架 提供
的基于 vector 的集合类型。
向量
虽然我们之前已经在 向量部分 中介绍过 vector
类型,但在新的上下文中再
次回顾它还是很有意义的。这一次,我们将介绍如何在对象中使用 vector
类型以及如何在应用程序中使用它。
module book::collections_vector {
use std::string::String;
/// The Book that can be sold by a `BookStore`
public struct Book has key, store {
id: UID,
name: String
}
/// The BookStore that sells `Book`s
public struct BookStore has key, store {
id: UID,
books: vector<Book>
}
}
VecSet
VecSet
是一种用于存储一组唯一项目的集合类型。它类似于 vector
,但它不允许重复的项目。这使得它非常
适合存储一组唯一的项目,例如唯一 ID 或地址列表。
VecSet 在尝试插入已存在于集合中的项时将失败。
VecMap
VecMap
是一种用于存储键值对映射的集合类型。它类似于 VecSet
,但它允许您将一个值与集合中的每个项目
相关联。这使得它非常适合存储键值对集合,例如地址及其余额列表,或者用户 ID 及其关联数据列表。
VecMap
中的键是唯一的,每个键只能与单个值相关联。如果您尝试插入一个键值对,其中键已经存在于映射中
,则旧值将被新值替换。
module book::collections {
use std::string::String;
use sui::vec_map::{Self, VecMap};
public struct Metadata has drop {
name: String,
/// `VecMap` used in the struct definition
attributes: VecMap<String, String>
}
#[test]
fun vec_map_playground() {
let mut map = vec_map::empty(); // create an empty map
map.insert(2, b"two".to_string()); // add a key-value pair to the map
map.insert(3, b"three".to_string());
assert!(map.contains(&2), 0); // check if a key is in the map
map.remove(&2); // remove a key-value pair from the map
}
}
限制
标准集合类型是一种存储类型数据并保证安全性和一致性的好方法。但是,它们受到可以存储的数据类型的限制( 类型系统不允许您在集合中存储错误的类型);并且它们受到大小的限制(对象大小限制)。它们适用于相对较小 的集合和列表,但对于更大的集合,您可能需要使用不同的方法。
集合类型的另一个限制是无法比较它们。因为插入顺序不是确定的,所以尝试将一个 VecSet
与另一个
VecSet
进行比较可能不会产生预期的结果。
此行为会由 linter 捕获并发出警告:比较类型为 'sui::vec_set::VecSet' 的集合可能会产生意外的结果
let mut set1 = vec_set::empty();
set1.insert(1);
set1.insert(2);
let mut set2 = vec_set::empty();
set2.insert(2);
set2.insert(1);
assert!(set1 == set2, 0);
在上面的例子中,比较会失败,因为插入顺序不是确定的,并且两个 VecSet
实例可能具有不同的元素顺序。即
使两个 VecSet
实例包含相同的元素,比较也会失败。
总结
- 向量是一种原生类型,允许存储项目列表。
- VecSet 基于向量构建,允许存储唯一项目的集合。
- VecMap 用于以类似映射的结构存储键值对。
- 基于 vector 的集合严格类型化,并受对象大小限制,最适合小型集合和列表。