英文原文档: https://book.clarity-lang.org/ch04-03-maps.html
Maps 映射
数据映射也可以被称作哈希表。它是一种允许您将键映射到特定值的数据结构。与元组键不同,数据映射键不是硬编码的名称。它们被表示为特定的具体值。如果要将数据与其他数据相关联,则应使用映射。
使用 define-map 定义映射:
(define-map map-name key-type value-type)
key-type 和 value-type 都可以是任何有效的类型签名,因为它们的多功能性,也通常会使用元组
;; A map that creates a principal => uint relation.
(define-map balances principal uint)
;; Set the "balance" of the tx-sender to u500.
(map-set balances tx-sender u500)
;; Retrieve the balance.
(print (map-get? balances tx-sender))
让我们来看看我们如何使用映射来存储和读取不同订单 ID 的基本信息。我们将使用一个无符号整数作为键类型,使用一个元组作为值类型。这些虚构的订单将有一个主体用户和金额。
(define-map orders uint {maker: principal, amount: uint})
;; Set two orders.
(map-set orders u0 {maker: tx-sender, amount: u50})
(map-set orders u1 {maker: tx-sender, amount: u120})
;; retrieve order with ID u1.
(print (map-get? orders u1))
值得注意的是:映射是不可迭代的。换句话说,您不能遍历映射并检索所有的值。访问映射中的值的唯一方法是指定正确的键。
键可以像您希望的那样设置成简单或复杂:
(define-map highest-bids
{listing-id: uint, asset: (optional principal)}
{bid-id: uint}
)
(map-set highest-bids {listing-id: u5, asset: none} {bid-id: u20})
虽然元组使代码更具可读性,但请记住 Clarity 是解释性的语言。使用元组作为键会比使用原始类型产生更高的执行成本。如果你的元组键只有一个成员,可以考虑直接使用成员类型作为映射键类型。
设置和插入
map-set 函数将覆盖现有值,但如果指定的键已存在,则 map-insert 将执行失败。也可以使用 map-delete 删除输入。
(define-map scores principal uint)
;; Insert a value.
(map-insert scores tx-sender u100)
;; This second insert will fail because the key already exists.
(map-insert scores tx-sender u200)
;; The score for tx-sender will be u100.
(print (map-get? scores tx-sender))
;; Delete the entry for tx-sender.
(map-delete scores tx-sender)
;; Will return none because the entry got deleted.
(print (map-get? scores tx-sender))
从映射读取可能会失败
我们从前面的例子中看到的是 map-get?返回一个optional 类型。原因是如果提供的键不存在,从映射中读取会失败。当这种情况发生时,map-get ?返回一个 none 。这也意味着,如果您希望使用检索到的值,在大多数情况下您必须将其解包。
;; A map that creates a string-ascii => uint relation.
(define-map names (string-ascii 34) principal)
;; Point the name "Clarity" to the tx-sender.
(map-set names "Clarity" tx-sender)
;; Retrieve the principal related to the name "Clarity".
(print (map-get? names "Clarity"))
;; Retrieve the principal for a key that does not exist. It will return `none`.
(print (map-get? names "bogus"))
;; Unwrap a value:
(print (unwrap-panic (map-get? names "Clarity")))
你可以通过这遍章节了解更多关于unwrap 的功能。