7.3 存储映射 (Storage Maps)
Another important common collection is the storage map. The type StorageMap<K, V>
from the standard library stores a mapping of keys of type K
to values of type V
using a hashing function, which determines how it places these keys and values into storage slots. This is similar to Rust's HashMap<K, V>
but with a few differences.
另一个重要的公共集合是存储映射。标准库中的类型 StorageMap<K, V>
使用哈希函数存储类型 K
的键到类型 V
的值的映射,这决定了如何将这些键和值放入 存储槽。这类似于 Rust 的 HashMap<K, V>,但有一些差异。
Storage maps are useful when you want to look up data not by using an index, as you can with vectors, but by using a key that can be of any type. For example, when building a ledger-based sub-currency smart contract, you could keep track of the balance of each wallet in a storage map in which each key is a wallet’s Address
and the values are each wallet’s balance. Given an Address
, you can retrieve its balance.
当您不想像使用向量那样使用索引来查找数据,而是使用可以是任何类型的键来查找数据时,存储映射很有用。例如,在构建基于分类帐的子货币智能合约时,您可以在存储映射中跟踪每个钱包的余额,其中每个键是钱包的Address 地址
,值是每个钱包的余额。给定一个 Address
,您可以检索其余额。
Similarly to StorageVec<T>
, StorageMap<K, V>
can only be used in a contract because only contracts are allowed to access persistent storage.
与StorageVec<T>
类似,StorageMap<K, V>
只能在合约中使用,因为只有合约才允许访问持久存储。
StorageMap<T>
is included in the standard library prelude which means that there is no need to import it manually.
StorageMap<T>
包含在 标准库前置 中,这意味着无需手动导入。
创建一个新的存储映射 (Creating a New Storage Map)
To create a new empty storage map, we have to declare the map in a storage
block as follows:
要创建一个新的空存储映射,我们必须在 storage
块中声明该映射,如下所示:
Just like any other storage variable, two things are required when declaring a StorageMap
: a type annotation and an initializer. The initializer is just an empty struct of type StorageMap
because StorageMap<K, V>
itself is an empty struct! Everything that is interesting about StorageMap<K, V>
is implemented in its methods.
就像任何其他存储变量一样,声明 StorageMap
时需要两件事:类型注释和初始化程序。初始化器只是一个 StorageMap
类型的空结构,因为 StorageMap<K, V>
本身是一个空结构! StorageMap<K, V>
的所有有趣之处都在其方法中实现。
Storage maps, just like Vec<T>
and StorageVec<T>
, are implemented using generics which means that the StorageMap<K, V>
type provided by the standard library can map keys of any type K
to values of any type V
. In the example above, we’ve told the Sway compiler that the StorageMap<K, V>
in map
will map keys of type Address
to values of type u64
.
存储映射,就像Vec<T>
和StorageVec<T>
一样,是使用泛型实现的,这意味着标准库提供的StorageMap<K, V>
类型可以映射任何类型的键K
到任何类型V
的值。在上面的示例中,我们告诉 Sway 编译器,map
中的StorageMap<K, V>
会将类型为 Address
的键映射到类型为 u64
的值。
更新存储映射 (Updating a Storage Map)
To insert key-value pairs into a storage map, we can use the insert
method, as shown below:
要将键值对插入存储映射,我们可以使用 insert
方法,如下所示:
Note two details here. First, in order to use insert
, we need to first access the storage map using the storage
keyword. Second, because insert
requires writing into storage, a #[storage(write)]
annotation is required on the ABI function that calls insert
.
这里注意两个细节。首先,为了使用 insert
,我们需要先使用 storage
关键字访问存储映射。其次,因为 insert
需要 写入 到存储中,所以调用 insert
的 ABI 函数需要一个 #[storage(write)]
注释。
Note The storage annotation is also required for any private function defined in the contract that tries to insert into the map. 注意 合约中定义的,试图插入地图的任何私有函数也需要存储注释。
Note There is no need to add the
mut
keyword when declaring aStorageMap<K, V>
. All storage variables are mutable by default. 注意 声明StorageMap<K, V>
时无需添加mut
关键字。默认情况下,所有存储变量都是可变的。
访问存储映射中的值 (Accessing Values in a Storage Map)
We can get a value out of the storage map by providing its key
to the get
method, as shown below:
我们可以通过向 get 方法提供其 key 来从存储映射中获取值,如下所示:
Here, value1
will have the value that's associated with the first address, and the result will be 42
. The get
method returns an Option<V>
; if there’s no value for that key in the storage map, get
will return Option::None
. This program handles the Option
by calling unwrap_or
to set value1
to zero if map
doesn't have an entry for the key.
此处,value1
将具有与第一个地址关联的值,结果将为 42
。 get
方法返回一个 Option<V>
;如果存储映射中该键没有值,get
将返回Option::None
。该程序通过调用 unwrap_or
来处理 Option
,如果 map
没有键的条目,则将 value1
设置为零。
具有多个键的存储映射 (Storage Maps with Multiple Keys)
Maps with multiple keys can be implemented using tuples as keys. For example:
可以使用元组作为键来实现具有多个键的映射。例如:
嵌套存储映射 (Nested Storage Maps)
It is possible to nest storage maps as follows:
可以按如下方式嵌套存储映射:
The nested map can then be accessed as follows:
然后可以按如下方式访问嵌套映射:
Last updated