如何在下面的代码示例中将新的空Parent实例添加到父项列表中?我一直在
UnimplementedFeatureError: Copying of type struct Test.Child memory[] memory
to storage not yet supported.
最小例子:
contract Test {
struct Child { }
struct Parent { Child[] children; }
Parent[] parents;
function test() {
parents.push(Parent(new Child[](0)));
}
}
答案 0 :(得分:8)
你无法真正做到你想要用动态数组做的事情。您需要稍微改变一下方法才能使其发挥作用。
contract Test {
struct Child { }
struct Parent {
mapping(uint => Child) children;
uint childrenSize;
}
Parent[] parents;
function testWithEmptyChildren() public {
parents.push(Parent({childrenSize: 0}));
}
function testWithChild(uint index) public {
Parent storage p = parents[index];
p.children[p.childrenSize] = Child();
p.childrenSize++;
}
}
如果您需要在合同中的其他位置迭代Parent.childrenSize
,请使用Parent.children
。
或者,您可以增加parents
数组的大小并使用Solidity的默认零值。
contract Test {
struct Child { }
struct Parent { Child[] children; }
Parent[] parents;
function test() public {
parents.length++;
Parent storage p = parents[parents.length - 1];
Child memory c;
p.children.push(c);
}
}
答案 1 :(得分:1)
如果子数组类型是另一种结构,则不起作用(至少从Solidity 0.4.24开始),但如果子数组类型是诸如uint256
之类的原始类型,则它起作用。
因此,如果您有
struct Child {
uint256 x;
bytes32 y;
}
然后您可以定义:
struct Parent {
uint256[] childXs;
bytes32[] childYs;
}
然后您可以写:
parents.push(Parent({
childXs: new uint256[](0),
childYs: new bytes32[](0)
}));
(当您要将结构体数组作为参数传递给公共函数时,可以采用相同的解决方法。)
这不理想,但是可以。
P.S。实际上(如果您使用的是原始数组子级),您可以编写:
Parent memory p;
parents.push(p);