表格 - Table

表格是一种类似映射的集合。它们在底层使用动态字段,并将键和值存储在对象系统中。这使得表格成为一种高效且灵活的数据结构, 可以存储多达一千条记录,这也是动态字段的限制。表格并不直接存储在对象系统中,而只是对象系统中的句柄。 当开发人员需要存储大量数据时,例如用于白名单,他们应该使用表格。需要注意的是,表格中的键和值的类型有一些限制。

键的类型必须具有 copydropstore 能力,而值的类型必须具有 store 能力。这是因为表格需要能够复制键,并且需要在对象系统中存储值。 一般来说,所有原始类型(数字、布尔值等)都可以用作键和值。自定义结构需要遵循上述规则,才能在表格中用作键或值。请注意,表格也是对象, 因为 Table 结构具有 UID 字段和 key 能力。这意味着它们可以独立于其他对象存在或被包含在其他对象中。

创建表格的方法如下:

let table = table::new<u64, bool>();

如果在创建后立即向表格添加条目,则不需要类型说明 <u64, bool>。键和值的类型将从添加到表格的第一个条目中推断出来。

let table = table::new();
// 创建一个类型为 <string, u64> 的表格:
table::add(&mut table, string::utf8(b"My key"), 1);

从表格中读取值的方法

let table = table::new<u64, bool>();
table::add(&mut table, 0, false);
let value = table::borrow(&table, 0);

如果值具有 copy 能力,可以通过解引用来复制它:

let value = *table::borrow(&table, 0);

直接修改表格中的值的方法:

let value = table::borrow_mut(&table, 0);
*value = true;

要从表格中移除一个值,我们需要键:

let table = table::new<u64, bool>();
table::add(&mut table, 0, false);
let value = table::remove(&mut table, 0);

请注意,remove 会返回该值,以便在移除后使用,或者在值不具有 drop 能力(因此不能自动删除)时使用。

表格不具有 drop 能力,当所有项目被移除时需要显式销毁:

let table = table::new<u64, bool>();
table::add(&mut table, 0, false);
table::remove(&mut table, 0);
table::destroy_empty(table);

如果值具有 drop 能力,表格在未清空时也可以销毁。然而,在这里需要注意的是,丢弃包含大量值的大表可能会消耗大量的 gas:

let table = table::new<u64, MyStruct>();
table::add(&mut table, 0, MyStruct());
table::drop(table);