为何Solidity中new关键字可创建合约实例却无法创建结构体实例?
Solidity中new关键字在结构体数组中报错:TypeError: Identifier is not a contract的原因
问题背景
我成功编写Solidity合约,通过new关键字在合约数组中创建并添加contractone合约实例。但尝试用同样方式,在结构体数组中使用new创建people结构体实例时,触发错误:TypeError: Identifier is not a contract。想请教该场景下new关键字失效的原因。
相关代码
可正常运行的合约代码
//SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./contractone.sol" ; contract contracttwo { contractone[] public deploy ; function contwo() public { deploy.push(new contractone()); // 用new添加contractone实例 } }
报错的合约代码
//SPDX-License-Identifier: MIT pragma solidity 0.8.16 ; contract arr { people[] public person ; struct people { uint256 num ; string name ; } function plus() public { person.push(new people()); // 用new创建people实例时报错 } }
原因分析及解决方案
在Solidity中,new关键字有明确的使用边界:
- 仅用于部署并创建新的合约实例(这就是第一个代码块能正常运行的原因);
- 或用于创建动态数组(比如
uint[] memory arr = new uint[](5))。
结构体属于自定义值类型,并非合约,因此不能用new来创建其实例。创建结构体实例的正确方式是直接用结构体名称结合初始化参数:
- 带键名的清晰初始化:
people({num: 0, name: ""}) - 按结构体成员定义顺序的简洁初始化:
people(0, "")
修正后的报错代码如下:
//SPDX-License-Identifier: MIT pragma solidity 0.8.16 ; contract arr { people[] public person ; struct people { uint256 num ; string name ; } function plus() public { // 用正确方式创建结构体实例并推入数组 person.push(people({num: 0, name: ""})); // 或者用顺序初始化:person.push(people(0, "")); } }
内容的提问来源于stack exchange,提问作者Brijesh Roy
相关产品推荐
相关产品推荐

