英文原文档: 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 的功能。