You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NEAR AssemblyScript合约PersistentUnorderedMap使用及初始化后存储不显示问题

问题根因

这个现象是NEAR AssemblyScript SDK的持久化结构序列化规则和PersistentUnorderedMap的懒初始化特性导致的,具体原因如下:

  • PersistentMap的结构非常简单,仅包含_elementPrefix这一个实例属性,你在构造函数中完成实例化时该属性就已经被赋值,所以合约状态序列化时会直接把它写入存储
  • PersistentUnorderedMap为了支持遍历、长度查询等能力,内部需要额外维护_keys(键列表)、_values(值列表)、_length(元素个数)三个辅助属性,这些属性默认只有在第一次执行写入操作时才会被初始化赋值,空的PersistentUnorderedMap实例在序列化时会被判定为无有效属性,所以不会出现在返回的状态结构中

这个情况不影响PersistentUnorderedMap的正常功能,只要你第一次调用set方法写入数据后,它的完整结构就会自动出现在合约存储里。

正确使用PersistentUnorderedMap的方式

基础规则

  • 实例化时传入的前缀必须和合约内其他所有持久化结构的前缀唯一,避免存储冲突,你当前代码里的前缀pma是符合要求的
  • 不需要强制要求初始化阶段就出现在存储中,正常执行业务写入逻辑后它会自动完成存储初始化
  • 不要手动修改PersistentUnorderedMap的内部属性,所有操作都通过官方提供的API执行

常用操作示例

// 写入数据
this.vehicleOwnersPmap.set(
  "account-id.testnet", 
  new VehicleOwner("account-id.testnet", "2024-05-20")
);

// 读取数据,第二个参数为不存在时返回的默认值
const owner = this.vehicleOwnersPmap.get("account-id.testnet", null);

// 判断键是否存在
const hasOwner = this.vehicleOwnersPmap.contains("account-id.testnet");

// 获取所有键/所有值
const allOwners = this.vehicleOwnersPmap.values();
const allAccounts = this.vehicleOwnersPmap.keys();

// 删除数据
this.vehicleOwnersPmap.delete("account-id.testnet");

// 获取元素个数
const count = this.vehicleOwnersPmap.length;

特殊场景处理

如果业务要求初始化阶段就必须在存储中看到PersistentUnorderedMap的结构,可以在构造函数中写入一条临时占位数据后再删除,即可触发存储初始化:

constructor(public vehicle:string = 'Mini') {
  this.vehicleOwners = new PersistentMap<AccountId, VehicleOwner>("vo");
  this.vehicleOwnersPmap = new PersistentUnorderedMap<AccountId,VehicleOwner>("pma");
  // 触发存储初始化
  const tempAccount = "init_placeholder" as AccountId;
  this.vehicleOwnersPmap.set(tempAccount, new VehicleOwner(tempAccount, ""));
  this.vehicleOwnersPmap.delete(tempAccount);
}

内容的提问来源于stack exchange,提问作者andy-dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 03:15:03