能否将uint256[100] memory强制转换为uint256[10] memory类型?
Solidity数组子切片返回方案
报错原因
Solidity中不同长度的固定长度数组属于完全独立的类型,uint256[100]和uint256[10]不存在兼容关系,不支持直接强转,因此你的代码会触发类型转换错误。
常见问题解答
- 能否直接返回storage数组的子切片引用?
不能。固定长度数组的类型由编译期确定长度,storage引用无法直接切出不同长度的数组实例;动态storage数组也不支持原生返回子切片引用,所有子切片返回都需要做元素拷贝。 - 是否需要将返回值设置为calldata类型?
不需要也不能这么做。calldata只能用于修饰外部函数的入参,无法作为返回值的存储位置声明,返回数组类结果统一使用memory类型即可。
正确实现代码
固定长度数组取前10个元素
contract Test { uint256[100] private foo; function get() external view returns (uint256[100] memory) { return foo; } function getFirst10() external view returns (uint256[10] memory res) { for(uint256 i = 0; i < 10; i++) { res[i] = foo[i]; } return res; } }
动态数组取任意子切片
如果是动态长度的存储数组,可以用以下通用实现:
contract TestDynamic { uint256[] private foo; // 返回从start下标开始、长度为length的子切片 function getSlice(uint256 start, uint256 length) external view returns (uint256[] memory res) { require(start + length <= foo.length, "索引超出数组范围"); res = new uint256[](length); for(uint256 i = 0; i < length; i++) { res[i] = foo[start + i]; } return res; } }
补充说明
当前Solidity 0.8.x版本仅支持对calldata类型的动态数组做原生切片操作,storage和memory类型的数组暂不支持原生切片能力。
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

