菜单

集合与存储

相关源文件

本页面介绍了 Sway 标准库中提供的集合类型和存储抽象。集合类型是用于组织和管理元素组的基本数据结构,而存储抽象则提供了在区块链上持久化数据的机制。

内存集合

内存集合是仅在合约执行期间存在于内存中的数据结构。当交易完成后,这些集合将被清除,并且不会持久化到区块链的存储中。

Vec

VVec<T> 类型是一种可增长的、堆分配的数组。它允许在内存中连续存储相同类型的多个值,并提供了添加、移除和访问元素的方法。

来源: [sway-lib-std/src/vec.sw:14-134], [sway-lib-std/src/vec.sw:147-299], [sway-lib-std/src/vec.sw:849-877]

核心功能

  • 堆分配:在堆上动态分配内存
  • 泛型:可以存储任何类型 T
  • 可增长:在需要时自动增长容量
  • 随机访问:通过索引提供常数时间访问元素

关键方法

方法描述复杂性
new()创建一个新的空向量O(1)
with_capacity(capacity)创建一个预分配空间的向量O(1)
push(value)在末尾添加一个元素均摊 O(1)
pop()移除并返回最后一个元素O(1)
get(index)返回指定索引处的元素O(1)
len()返回元素数量O(1)
is_empty()返回向量是否为空O(1)
remove(index)移除并返回指定索引处的元素O(n)
insert(index, element)在指定索引处插入一个元素O(n)
clear()移除所有元素O(1)
iter()返回向量的迭代器O(1)

来源: [sway-lib-std/src/vec.sw:153-685], [test/src/in_language_tests/test_programs/vec_inline_tests/src/main.sw:13-520]

示例

来源: [test/src/in_language_tests/test_programs/vec_inline_tests/src/main.sw:399-414]

Bytes

Bytes 类型是一个专门为处理原始字节数据而设计的集合。它类似于 Vec<u8>,但针对字节操作进行了优化。

来源: [sway-lib-std/src/bytes.sw:15-56], [sway-lib-std/src/bytes.sw:91-125], [test/src/in_language_tests/test_programs/bytes_inline_tests/src/main.sw:1-877]

核心功能

  • 字节优化:专门用于处理字节数据
  • 内存高效:字节存储紧密打包
  • API相似性:类似于 Vec<u8>,但具有字节专用方法
  • 转换:提供与 b256 及其他类型之间的转换

关键方法

方法描述复杂性
new()创建一个新的空字节集合O(1)
with_capacity(capacity)创建一个预分配空间的字节集合O(1)
push(byte)在末尾添加一个字节均摊 O(1)
pop()移除并返回最后一个字节O(1)
get(index)返回指定索引处的字节O(1)
len()返回字节数量O(1)
is_empty()返回字节集合是否为空O(1)
remove(index)移除并返回指定索引处的字节O(n)
insert(index, byte)在指定索引处插入一个字节O(n)
clear()移除所有字节O(1)
split_at(mid)在给定索引处分割成两部分O(n)
append(other)追加另一个 BytesO(n)
splice(start, end, replace_with)用新字节替换一个范围O(n)

来源: [sway-lib-std/src/bytes.sw:98-877], [test/src/in_language_tests/test_programs/bytes_inline_tests/src/main.sw:10-568]

示例

来源: [test/src/in_language_tests/test_programs/bytes_inline_tests/src/main.sw:39-83], [test/src/in_language_tests/test_programs/bytes_inline_tests/src/main.sw:338-380]

U128

U128 类型支持128位无符号整数,表示为两个64位组件。

来源: [sway-lib-std/src/u128.sw:25-30], [sway-lib-std/src/u128.sw:271-507]

实现细节

  • 表示为两个64位组件:(upper, lower)
  • 值计算为 (upper << 64) + lower
  • 支持与各种整数类型之间的转换
  • 实现带溢出处理的算术运算

来源: [sway-lib-std/src/u128.sw:24-30], [sway-lib-std/src/u128.sw:510-707]

存储集合

存储集合在区块链上提供持久数据存储。与内存集合不同,存储在这些集合中的数据在交易之间是持久的,并且可以在合约的不同调用中访问。

存储架构

来源: [sway-lib-std/src/storage.sw:1-11], [sway-lib-std/src/prelude.sw:17-18]

在 Sway 中,存储通过基于键的系统进行访问。每个存储项都由一个唯一的 StorageKey 标识,用于读写区块链存储。

StorageMap

StorageMap 是一个键值存储,将数据持久化到区块链上。它类似于哈希图,但将数据存储在合约存储中而非内存中。

来源: [sway-lib-std/src/prelude.sw:17], [test/src/sdk-harness/test_projects/storage_map/mod.rs:1-562]

主要功能

  • 持久性:存储的数据在交易之间持久存在
  • 泛型:可以存储任何可哈希的键值对
  • CRUD 操作:支持插入、检索和删除
  • 类型安全:提供类型安全的存储访问

常用操作

操作描述
insert(key, value)将值存储在指定的键上
get(key)检索指定键的值
remove(key)移除指定键的值
contains(key)检查映射中是否存在键
try_insert(key, value)尝试在键不存在时插入值

来源: [test/src/sdk-harness/test_projects/storage_map/mod.rs:28-561], [test/src/sdk-harness/test_projects/storage_map/try_insert.rs]

示例

来源: [test/src/sdk-harness/test_projects/storage_map/mod.rs:33-49]

其他存储集合

Sway 标准库包含额外的存储集合

StorageVec

一种类似向量的集合,按顺序将元素存储在合约存储中。

StorageBytes

一个字节专用存储集合,类似于 Bytes,但存储在合约存储中。

StorageString

一个字符串存储集合,用于在合约存储中存储和操作 UTF-8 编码的文本。

来源: [sway-lib-std/src/storage.sw:5-10]

最佳实践

何时使用内存集合与存储集合

  • 内存集合:用于交易内的临时数据处理
  • 存储集合:用于需要在交易之间持久化存储的数据

性能考量

  • 相比内存操作,读写存储在 Gas 方面更昂贵
  • 尽可能减少存储操作
  • 使用内存集合进行中间计算,只将最终结果存储到存储中

常见模式

  1. 读-计算-写:从存储读取,在内存中执行计算,然后写回存储
  2. 惰性加载:仅在需要时从存储加载数据
  3. 批量操作:尽可能批量处理存储操作以最小化 Gas 成本

来源: [test/src/sdk-harness/test_projects/storage_map/mod.rs:28-561]

错误处理

内存集合和存储集合都使用 Option<T>Result<T, E> 来处理可能失败的操作

  • 当检索可能不存在的元素时,使用 Option<T>
  • get() 这样的方法返回 Option<T> 而不是触发 panic
  • 可能失败的集合操作(例如越界访问)使用显式错误处理

来源: [sway-lib-std/src/option.sw:84-90], [sway-lib-std/src/result.sw:64-70]