sui move table 和 bag

  • shaflow01
  • 更新于 2024-03-03 15:16
  • 阅读 852

引言本文通过阅读分析table、bag的源码实现,深入理解此类型的使用方法和实现原理。

引言

本文通过阅读分析table、bag的源码实现,深入理解此类型的使用方法和实现原理。

table

上一篇文章我们阅读了dynamic_field源码,知道了动态字段的实现原理,那么在看table就会很简单了。table.move定义了一个Table结构体

    struct Table<phantom K: copy + drop + store, phantom V: store> has key, store {
        /// the ID of this table
        id: UID,
        /// the number of key-value pairs in the table
        size: u64,
    }

其实这个Table obj就是dynamic_field中为其增添子对象的object,这里来回忆一下

    public fun add<Name: copy + drop + store, Value: store>(
        // we use &mut UID in several spots for access control
        object: &mut UID,
        name: Name,
        value: Value,
    ) {
        let object_addr = object::uid_to_address(object);
        let hash = hash_type_and_key(object_addr, name);
        assert!(!has_child_object(object_addr, hash), EFieldAlreadyExists);
        let field = Field {
            id: object::new_uid_from_hash(hash),
            name,
            value,
        };
        add_child_object(object_addr, field)
    }

Table就是拥有filed的父对象,其中的size代表了拥有filed动态字段的数量,初始为0.
需要注意的是,Table结构体在创建时就指定好它能储存哪种类型的键值对struct Table<phantom K: copy + drop + store, phantom V: store> has key, store,不能储存不同类型的键值对。

创建

    public fun new<K: copy + drop + store, V: store>(ctx: &mut TxContext): Table<K, V> {
        Table {
            id: object::new(ctx),
            size: 0,
        }
    }

调用new创建返回一个Table obj,需要指定固定类型的key和value

增加/删除

    public fun add<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K, v: V) {
        field::add(&mut table.id, k, v);
        table.size = table.size + 1;
    }

    public fun remove<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K): V {
        let v = field::remove(&mut table.id, k);
        table.size = table.size - 1;
        v
    }

要注意的是,添加的key和value必须与table的两个phantom一致
实现很简单,调用dynamic_field的add remove方法,然后变更长度信息

获取

    public fun borrow<K: copy + drop + store, V: store>(table: &Table<K, V>, k: K): &V {
        field::borrow(&table.id, k)
    }

    /// Mutably borrows the value associated with the key in the table `table: &mut Table<K, V>`.
    /// Aborts with `sui::dynamic_field::EFieldDoesNotExist` if the table does not have an entry with
    /// that key `k: K`.
    public fun borrow_mut<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K): &mut V {
        field::borrow_mut(&mut table.id, k)
    }

同样是简单调用dynamic_field中的函数取得value的可变和不可变借用

其他函数

    public fun contains<K: copy + drop + store, V: store>(table: &Table<K, V>, k: K): bool {
        field::exists_with_type<K, V>(&table.id, k)
    }

    /// Returns the size of the table, the number of key-value pairs
    public fun length<K: copy + drop + store, V: store>(table: &Table<K, V>): u64 {
        table.size
    }

    /// Returns true iff the table is empty (if `length` returns `0`)
    public fun is_empty<K: copy + drop + store, V: store>(table: &Table<K, V>): bool {
        table.size == 0
    }

    /// Destroys an empty table
    /// Aborts with `ETableNotEmpty` if the table still contains values
    public fun destroy_empty<K: copy + drop + store, V: store>(table: Table<K, V>) {
        let Table { id, size } = table;
        assert!(size == 0, ETableNotEmpty);
        object::delete(id)
    }

    /// Drop a possibly non-empty table.
    /// Usable only if the value type `V` has the `drop` ability
    public fun drop<K: copy + drop + store, V: drop + store>(table: Table<K, V>) {
        let Table { id, size: _ } = table;
        object::delete(id)
    }

contains判断table相应键是否存在
length返回table动态字段的数目
is_empty判断table是否为空
destroy_empty可以解构一个空的table
drop可以用来解构非空的table

bag

bag与table的差别在于 它可以储存不同类型的键值对 在bag的结构体定义时,bag没有规定键值的类型

    struct Bag has key, store {
        /// the ID of this bag
        id: UID,
        /// the number of key-value pairs in the bag
        size: u64,
    }

其他部分和table的实现一致

总结

table、bag是对dynamic_field的简单封装。其中,table限定了键值对的类型,在创建时需要指定类型,并且只能存储相同类型的键值对;而bag则是一种更灵活的数据结构,可以存储不同类型的键值对。通过本文的阐述,应该可以更深入地理解这两种数据结构的使用方法和实现原理,从而更好地应用于实际的开发中。

Move语言学习交流QQ群: 79489587 Sui官方中文开发者电报群: https://t.me/sui_dev_cn

  • 原创
  • 学分: 6
  • 分类: Sui
  • 标签:
点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
shaflow01
shaflow01
0x4937...bA76
江湖只有他的大名,没有他的介绍。