Solidity嵌套struct开发时addDrugs调用报Integer constant expected错误
错误产生原因
- 直接触发编译报错的核心问题:你错误地将结构体类型名
Drug作为数组/映射变量使用,写出了Drug[_id]这类非法语法。Solidity中类型名[整数常量]是固定长度数组的声明语法,要求方括号内必须是编译期就能确定值的整型常量;编译器看到Drug[_id]时,会判定你在尝试声明一个固定长度的Drug类型数组,但方括号内的_id是运行时才会赋值的循环变量,不是常量,因此抛出TypeError: Integer constant expected错误。 - 代码附带的多处逻辑缺陷:
addDrugs函数第一行强制将传入的_id赋值为1,无论传入什么参数,最终都只会操作mapDrug中key为1的存储槽,循环调用时所有药品数据会互相覆盖,完全无法实现批量存药。addPresc入参设计不合理:单个Drug memory _list只能接收1个药品实例,无法支持处方包含多个药品的需求;且处方ID硬编码为1,每次调用函数都会覆盖同一条处方记录,无法生成多个独立处方。- 数据关联缺失:存药品时没有将药品实例写入对应处方的
drugs动态数组成员,处方和药品数据完全割裂,不符合最初的结构体设计目标。 - 冗余参数风险:手动传入的
_nbOfDrugs参数没有和实际药品数量做校验,很容易出现参数值和实际药品数不一致的逻辑bug。
修复方案
修复逻辑围绕「解决语法错误、补全数据关联、修正ID生成逻辑、移除冗余设计」四个核心点调整,修复后可直接编译运行的完整代码如下:
pragma solidity ^0.8.0; contract Pharm { struct Presc { uint id; uint ref; uint nbOfDrugs; string Pname; Drug[] drugs; } struct Drug { uint id; string name; uint Qtt; } Drug[] drugss; mapping(uint=> Presc) public mapPresc; mapping(uint=> Drug) public mapDrug; // 全局自增ID,解决硬编码ID导致的数据覆盖问题 uint public prescIdCounter = 1; uint public drugIdCounter = 1; // 仅允许合约内部调用,避免外部随意篡改药品数据 function addDrugs(uint _belongPrescId, string memory _name, uint _Qtt) internal { uint currentDrugId = drugIdCounter; Drug storage newDrug = mapDrug[currentDrugId]; newDrug.id = currentDrugId; newDrug.name = _name; newDrug.Qtt = _Qtt; // 将新增药品关联到对应处方的drugs数组 mapPresc[_belongPrescId].drugs.push(newDrug); drugIdCounter++; } // 入参改为Drug动态数组,支持批量传入任意数量的药品 function addPresc(uint _ref, string memory _Pname, Drug[] memory _drugList) public { uint currentPrescId = prescIdCounter; Presc storage presc = mapPresc[currentPrescId]; presc.id = currentPrescId; presc.ref = _ref; // 直接取传入药品数组的长度作为药品总数,避免手动传参的不一致问题 presc.nbOfDrugs = _drugList.length; presc.Pname = _Pname; // 遍历传入的药品列表,逐个完成存证、关联 for(uint i = 0; i < _drugList.length; i++){ addDrugs(currentPrescId, _drugList[i].name, _drugList[i].Qtt); } prescIdCounter++; } }
关键修改点说明:
- 完全移除了非法的
Drug[_id]写法,循环遍历时直接读取传入的内存药品数组的元素属性,从根源解决编译错误。 - 删除
addDrugs中强制将ID赋值为1的错误逻辑,改用全局自增ID生成药品、处方的唯一标识,避免数据互相覆盖。 - 补全了药品和处方的关联逻辑,新增药品时自动推入对应处方的
drugs动态数组,符合最初的结构体设计。 - 调整函数可见性:将仅用于内部逻辑的
addDrugs改为internal,避免外部非法调用;移除冗余的_nbOfDrugs入参,直接通过数组长度获取药品总数,降低参数传错的风险。
内容的提问来源于stack exchange,提问作者Imen
相关产品推荐
相关产品推荐

