Solidity

如何初始化結構內的空數組?

  • February 3, 2021

我在函式 foobar 中初始化 Bar b 的方式有錯誤嗎?

contract Foo {

   struct Bar {
       address owner;
       uint[] x;
   }

   Bar[] public bars;

   function foobar(address a) public {
       Bar storage b = Bar(a, new uint[]) // will that be an array in storage?
       bars.push(b)
   }

}

在 Solidity 中不需要初始化storage數組。只有memory數組必須在使用前進行初始化。

因此,在您的情況下,x只要您Bar沒有將值分配給. 實際上,在您的程式碼中進行初始化會無緣無故地消耗氣體。x``foobar

以下程式碼適用於您的情況:

function foobar(address a) public {
   Bar memory b;
   b.owner = a;
   //When 'b' is pushed to 'bars' array:
   // (1) 'b' will be converted from memory to storage.
   // (2) And 'x' inside it will be initialized automatically.
   bars.push(b); 
}

但是,如果您需要訪問 x 並推送一些值,您可以使用push

function foobar2(address a, uint x0) public {
   Bar memory b;
   b.owner = a;
   bars.push(b);
   //Trying: b.x[0] = x0; will generate error. Since, b.x is a memory array that is not initialized!
   bars[bars.length - 1].x.push(x0); //This will work fine!
}

實際上,您仍然可以將記憶體數組初始化為空數組,如下所示:

function foobar3(address a) public {
   Bar memory b = Bar(a, new uint[](0)); //Thanks to "James Duffy" for his answer.
   bars.push(b);
}

最後要提到的是:如果你有多個值,你需要插入到你的x數組中,那麼你可以這樣做:

function foobar4(address a, uint[] _x) public {
   Bar memory b = Bar(a, _x);
   bars.push(b);
}

或如下。但是,這會消耗更多的氣體:

function foobar5(address a, uint[] _x) public {
   Bar memory b;
   b.owner = a;
   bars.push(b);

   Bar storage c = bars[bars.length - 1]; // Get the newly added instance of the storage struct
   for (uint i = 0; i < _x.length; i++) {
       c.x.push(_x[i]);
 }

在漂亮的 EthFiddler 上查看完整程式碼:https ://ethfiddle.com/fQI6Khgz3E

引用自:https://ethereum.stackexchange.com/questions/30857