Solidity public映射自动getter无法返回结构体数组问题
现象原因说明
这个问题的核心是Solidity编译器对public状态变量自动生成getter函数的固有规则限制,和数据是否上链、存储逻辑是否正确没有关系,具体逻辑如下:
- 所有public修饰的状态变量,编译器会自动生成对应的查询函数,但这个自动生成的函数不会支持返回嵌套了动态长度类型的完整复杂结构。当遇到结构体内部嵌套动态数组、映射这类长度不固定的类型时,自动getter不会把整个动态类型内容直接返回。
- 对应到这个测试合约:定义的
testStruct内部包含动态长度的address数组testArr,testMap的自动getter不会把整个结构体连带完整数组返回。它的实际逻辑是把嵌套的动态类型拆成需要额外传入索引参数的形式:如果要取testArr里指定下标的元素,你需要传入两个参数调用自动getter:第一个参数是映射的键(也就是你的地址),第二个参数是数组的下标,返回值是对应位置的单个address,拿不到整个数组。 - 你自己实现的
getStruct()是显式定义了返回值类型为address[] memory,函数逻辑直接从存储位置读取完整的动态数组,拷贝到内存后整体返回,完全不受自动getter生成规则的约束,所以可以正常返回完整的数组内容。
补充提示:如果需要返回包含动态数组成员的完整结构体、或者整个动态数组内容,不要依赖public变量的自动getter,必须手动编写对应的视图查询函数实现返回逻辑。
测试合约代码
contract TEST { struct testStruct { address[] testArr; } mapping(address => testStruct) public testMap; function addToStruct() public { test storage a = testMap[msg.sender]; a.testArr.push(msg.sender); } function getStruct() public view returns(address[] memory){ return testMap[msg.sender].testArr; } }
内容的提问来源于stack exchange,提问作者devChoi
相关产品推荐
相关产品推荐

