You need to enable JavaScript to run this app. Solidity返回动态数组报返回参数需指定memory的错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Solidity返回动态数组报返回参数需指定memory的错误如何解决

错误修正方案

报错根因拆解

  1. 直接触发当前TypeError的原因
    Solidity 0.6.0 版本中,public/external 函数的返回参数不允许指定storage作为数据位置。storage是指向链上持久存储的引用指针,跨函数调用返回时无法直接传递该类引用,所有对外返回的引用类型/值类型都必须放在memory数据位置,完成序列化后才能返回。
  2. 修正上述报错后会触发的隐藏问题
    你代码中当前初始化数组的逻辑不兼容Solidity语法:uint[] memory indices = new uint[](deposits.length) 创建的是定长内存数组,Solidity 0.6.0 版本中,memory类型的数组不支持push()方法(push是链上storage动态数组的专属操作),直接调用indices.push(i)会触发第二个编译错误。

具体修正步骤

  • 调整函数返回值定义,移除不合法的storage声明,改为内存位置返回:把returns (uint256 [] storage) 修改为returns (uint256[] memory)
  • 调整索引收集逻辑,适配memory定长数组的规则:
    • 第一次遍历存款数组,先统计符合「激活且未关闭」条件的存款总数量
    • 根据统计得到的数量,初始化对应长度的定长memory数组
    • 第二次遍历存款数组,将符合条件的索引按顺序写入memory数组的对应位置
    • 返回组装完成的数组

修正后可直接编译运行的代码

function getActiveDepositIndexes() public view returns (uint256[] memory) {
    User storage user = users[msg.sender];
    Deposit[] storage deposits = user.deposits;
    // 第一轮遍历:统计匹配条件的索引总数
    uint256 matchCount = 0;
    for(uint i = 0; i < deposits.length; i++) {
        if(deposits[i].active && !deposits[i].closed){
            matchCount++;
        }
    }
    // 按统计长度初始化内存数组
    uint256[] memory indices = new uint256[](matchCount);
    // 第二轮遍历:写入匹配的索引
    uint256 writeCursor = 0;
    for(uint i = 0; i < deposits.length; i++) {
        if(deposits[i].active && !deposits[i].closed){
            indices[writeCursor] = i;
            writeCursor++;
        }
    }
    return indices;
}

环境适配说明

上述写法完全兼容你当前使用的Truffle v5.1.20、Solidity 0.6.0版本配置,不需要升级依赖即可正常编译运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 01:45:07