尚不支持将类型 struct memory[] 内存复制到存储

Copying of type struct memory[] memory to storage not yet supported

如何将新的空 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)));
  }
}

你不能真正地做你想用动态数组做的事情。您需要稍微改变您的方法才能使其发挥作用。

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.children,请使用 Parent.childrenSize

或者,您可以增加 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);
  }
}

如果子数组类型是另一个结构,它就不起作用(至少从 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)
}));

(当您想将结构数组作为参数传递给 public 函数时,同样的解决方法适用。)

虽然不理想,但很管用。

P.S。实际上(如果你使用的是原始数组 children)你可以这样写:

Parent memory p;
parents.push(p);