Есть ли ошибка в том, как я инициализирую Bar b в функции foobar?
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://ethfiddle.com/Yn6fLiAjto
Один из способов выполнить эту работу — создать временный объект Bar
в памяти перед его отправкой bars
( Bar memory b
вместо Bar storage b
). Затем Solidity автоматически скопирует данные структуры из памяти в хранилище. См. https://ethereum.stackexchange.com/a/4476/22415 для более подробной информации.
Также new uint[]
есть функция, которая требует аргумента размера, например new uint[](8)
.
Таким образом, полностью эта строка должна читатьсяBar memory b = Bar(a, new uint[](8));
Попробуй это:
struct Address {
address[] addressList;
}
function createProposal() public {
address[] memory emptyAddressList;
Address memory _address = Address({
addressList: emptyAddressList
})
}
Мухаммад Альтабба
Артод
Артод