Solidity中为何无法使用状态变量定义定长数组长度?
错误原因
Solidity 中定长数组的长度必须是编译阶段就能确定值的常量表达式,不支持使用运行时才能赋值的变量作为定长数组长度:
- 你代码里的
size是普通状态变量,值需要合约部署后调用setSize才能设置,还可以反复调用修改,编译器在编译阶段无法确定数组的固定长度,没法提前分配对应存储空间,因此直接抛出编译错误。 - 代码中
getArray的返回值声明returns(uint[size] memory)存在相同问题:定长数组作为返回值时,长度同样要求是编译期可确定的常量。
修正方案
根据你是否需要动态调整数组长度,选对应方案即可:
方案1:使用动态数组(适配你动态设置size的需求)
如果数组长度需要部署后动态设置,直接改用动态长度数组即可,这也是这类场景的通用写法:
// SPDX-License-Identifier: MIT pragma solidity >=0.4.16 <0.9.0; contract check{ uint public size; // 声明为动态uint数组 uint[] arr; function setSize(uint s) public { size = s; // 初始化指定长度的动态数组 arr = new uint[](s); } function SetArray() public { for(uint i=0; i<size; i++){ arr[i] = i+1; } } function getArray() public view returns(uint[] memory){ return arr; } }
注意:如果重复调用setSize,重新执行new uint[](s)会覆盖原数组引用,导致之前存储的数组数据丢失。如果需要保留原有数据,要单独编写数组长度调整逻辑,不要直接重新初始化数组。
方案2:数组长度固定时声明为编译期常量
如果数组长度从一开始就固定不需要修改,可以把size声明为constant常量,让编译器在编译阶段就能拿到长度值,就可以正常使用定长数组:
// SPDX-License-Identifier: MIT pragma solidity >=0.4.16 <0.9.0; contract check{ // 用constant修饰,值在编译期确定,部署后不可修改 uint public constant size = 10; uint[size] arr; function SetArray() public { for(uint i=0; i<size; i++){ arr[i] = i+1; } } function getArray() public view returns(uint[size] memory){ return arr; } }
内容的提问来源于stack exchange,提问作者Thermal Ice
相关产品推荐
相关产品推荐

