Что возвращает array.push() в Solidity?

Я видел эти строки кода в cryptozombies.io:

uint id = zombies.push(Zombie(_name, _dna)) - 1;
zombieToOwner[id] = msg.sender;

У меня не было бы проблем, если бы не было "- 1" после функции push(). Я считаю, что возвращаемое значение функции push как-то связано с индексом вставленного объекта. Почему там "-1"? Доступен ли индекс возвращаемого значения следующего свободного места для вставки следующего объекта в массив?

Ответы (4)

Из документации Solidity :

push : Массивы динамического хранения и bytes(не string) имеют функцию-член push(), которую можно использовать для добавления элемента, инициализированного нулем, в конец массива. Он возвращает ссылку на элемент, чтобы его можно было использовать как x.push().t = 2или x.push() = b.

Функция возвращает новую длину массива. Итак, если в массиве уже есть 1 элемент, и я нажимаю другой, это нажатие вернет новую длину, которая равна 2. Поскольку массивы имеют нулевой индекс, вам нужно вычесть единицу из длины, чтобы получить индекс последнего элемента , что и делает пример кода, который вы разместили.

Изменить: как указал @user8555937, это уже не так, начиная с Solidity 0.6.0. Функция push больше не имеет возвращаемого значения

Это больше не действует для Solidity 0.6.0: ethereum.stackexchange.com/a/87791/83404 .

Solidity 0.6.0 включает некоторые важные изменения :

Функция push(value) для динамических массивов хранения больше не возвращает новую длину (ничего не возвращает).

Теперь документация выглядит так:

push(x) : динамические массивы хранения и байты (не строки) имеют функцию-член с именем push(x), которую можно использовать для добавления заданного элемента в конец массива. Функция ничего не возвращает.

Теперь вы должны использовать .lengthатрибуты. В твоем случае :

zombies.push(Zombie(_name, _dna));
uint id = zombies.length - 1;

Эта array.push()функция доступна только для массивов хранения с динамическим размером. (например, вы не можете сделать array.push()дальше bytes32[10] array, так как это статический размер).

В этих случаях pushфункция возвращает новую длину массива, поэтому последний индекс всегда имеет длину -1, поскольку индексы начинаются с 0, а не с 1;

Вы можете проверить это здесь, если хотите: http://solidity.readthedocs.io/en/develop/types.html?highlight=array#members

Я думаю, что .push()на самом деле это означает добавление нового элемента в массив на большинстве других языков.

Чтобы вернуть длину массива, действительно имеет смысл иметь .length.