V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gitandgit
V2EX  ›  区块链

Clarity 智能合约开发语言|理解并使用 Maps 映射

  •  
  •   gitandgit · 2021-09-28 14:51:58 +08:00 · 575 次点击
    这是一个创建于 1186 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2699 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:05 · PVG 12:05 · LAX 20:05 · JFK 23:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.