Homogeneous Collections
在深入探讨在 Sui 上构建市场这一主题之前,让我们先了解一下 Move 中的集合。
Vectors
Move 中的 Vector
类似于其他语言(如 C++)中的 Vector。它是一种在运行时动态分配内存并管理一组单一类型的方法,可以是特定类型或通用类型。
需要注意的是,用泛型类型定义的向量可以接受任意类型的对象,集合中的所有对象仍然必须是相同类型,也就是说,集合是同质的。
创建vector
任何类型的向量都可以通过 vector
字面量和vector的API创建。
#![allow(unused)] fn main() { vector<T>[]: vector<T> vector<T>[e1, ..., en]: vector<T> }
一个简单的示例:
#![allow(unused)] fn main() { const A: vector<u8> = vector[0u8, 1u8, 2u8]; const B: vector<bool> = vector<bool>[false]; (vector[]: vector<bool>); (vector[0u8, 1u8, 2u8]: vector<u8>); (vector<u128>[]: vector<u128>); (vector<address>[@0x42, @0x100]: vector<address>); }
下面是一个自定义类型的vector,并封装了相关操作函数,请参阅包含的示例代码以 vector
的定义以及其基本操作。
#![allow(unused)] fn main() { module collection::vector { use std::vector; public struct Widget { } // Vector for a specified type public struct WidgetVector { widgets: vector<Widget> } // Vector for a generic type public struct GenericVector<T> { values: vector<T> } // Creates a GenericVector that hold a generic type T public fun create<T>(): GenericVector<T> { GenericVector<T> { values: vector::empty<T>() } } // Push a value of type T into a GenericVector public fun put<T>(vec: &mut GenericVector<T>, value: T) { vector::push_back<T>(&mut vec.values, value); } // Pops a value of type T from a GenericVector public fun remove<T>(vec: &mut GenericVector<T>): T { vector::pop_back<T>(&mut vec.values) } // Returns the size of a given GenericVector public fun size<T>(vec: &mut GenericVector<T>): u64 { vector::length<T>(&vec.values) } } }
更多可以通过movebook查看
Table
Table
是一个映射类的集合,可以动态存储键值对。但与传统的映射集合不同,它的键和值不存储在 Table
值中,而是使用 Sui 的对象系统存储。该 Table
结构仅充当对象系统的句柄以检索这些键和值。
Table
中一个 key
的类型必须具有 copy + drop + store
的能力约束,并且 value
类型必须具有 store
的能力约束。
Table
也是一种同构集合类型,其中键和值字段可以指定或泛型类型,但集合中的所有值和所有键 Table
必须是相同的类型。
测验:用运算符检查包含完全相同的键值对的两个表对象是否彼此相等 ===
?试试看。
有关使用集合的信息,请参见以下示例Table
:
#![allow(unused)] fn main() { module collection::table { use sui::table::{Table, Self}; use sui::tx_context::{TxContext}; // Defining a table with specified types for the key and value public struct IntegerTable { table_values: Table<u8, u8> } // Defining a table with generic types for the key and value public struct GenericTable<phantom K: copy + drop + store, phantom V: store> { table_values: Table<K, V> } // Create a new, empty GenericTable with key type K, and value type V public fun create<K: copy + drop + store, V: store>(ctx: &mut TxContext): GenericTable<K, V> { GenericTable<K, V> { table_values: table::new<K, V>(ctx) } } // Adds a key-value pair to GenericTable public fun add<K: copy + drop + store, V: store>(table: &mut GenericTable<K, V>, k: K, v: V) { table::add(&mut table.table_values, k, v); } /// Removes the key-value pair in the GenericTable `table: &mut Table<K, V>` and returns the value. public fun remove<K: copy + drop + store, V: store>(table: &mut GenericTable<K, V>, k: K): V { table::remove(&mut table.table_values, k) } // Borrows an immutable reference to the value associated with the key in GenericTable public fun borrow<K: copy + drop + store, V: store>(table: &GenericTable<K, V>, k: K): &V { table::borrow(&table.table_values, k) } /// Borrows a mutable reference to the value associated with the key in GenericTable public fun borrow_mut<K: copy + drop + store, V: store>(table: &mut GenericTable<K, V>, k: K): &mut V { table::borrow_mut(&mut table.table_values, k) } /// Check if a value associated with the key exists in the GenericTable public fun contains<K: copy + drop + store, V: store>(table: &GenericTable<K, V>, k: K): bool { table::contains<K, V>(&table.table_values, k) } /// Returns the size of the GenericTable, the number of key-value pairs public fun length<K: copy + drop + store, V: store>(table: &GenericTable<K, V>): u64 { table::length(&table.table_values) } } }