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

Substrate开发:如何使用try_mutate修改值为枚举的StorageMap?

问题解决

报错根因

  • try_mutate 闭包的入参 status 类型为 &mut Option<Gender>:这是指向Option<Gender>的可变引用,当目标AccountId不存在时*status为None,已存在时为Some(旧值)
  • 你的代码犯了两个典型类型错误:
    1. 没有对可变引用解引用,直接给引用本身赋值,类型不匹配
    2. 赋值内容是裸的Gender枚举值,不是要求的Option<Gender>类型

原有逻辑bug修复

你写的前置判断逻辑完全写反了:ensure!(hotel_status == Some(Gender::Active), <Error<T>>::HotelAlreadyActive); 代表「只有酒店已经是激活状态才允许往下执行,否则抛出酒店已激活的错误」,和你预期的「已激活就报错」逻辑相反,需要调整判断条件。

修正后完整代码

#[pallet::weight(0)]
pub fn activate_hotel(
    origin: OriginFor<T>,
    hotel: T::AccountId,
) -> DispatchResult {
    let sender = ensure_signed(origin)?;
    log::info!("signer ID: {:?}.", sender);
    let hotel_status = <HotelStatus<T>>::get(&hotel);
    // 修正判断:已激活则抛出错误
    ensure!(hotel_status != Some(Gender::Active), <Error<T>>::HotelAlreadyActive);
    
    // 一行完成存在则修改、不存在则插入的逻辑,无需手动写insert
    <HotelStatus<T>>::try_mutate(hotel, |status| -> DispatchResult {
        *status = Some(Gender::Active);
        Ok(())
    })?;
    
    Ok(())
}

通用操作说明

无论StorageMap的值是枚举、数字、字符串还是其他基础类型,try_mutate的使用逻辑完全统一:

  • 闭包入参永远是&mut Option<值类型>
  • 需要修改/插入值时先解引用*status,赋值为Some(新值)即可
  • 如果要删除对应key的存储条目,赋值为None即可

内容的提问来源于stack exchange,提问作者ReiGun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:15:02