Я видел эти строки кода в cryptozombies.io:
uint id = zombies.push(Zombie(_name, _dna)) - 1;
zombieToOwner[id] = msg.sender;
У меня не было бы проблем, если бы не было "- 1" после функции push(). Я считаю, что возвращаемое значение функции push как-то связано с индексом вставленного объекта. Почему там "-1"? Доступен ли индекс возвращаемого значения следующего свободного места для вставки следующего объекта в массив?
push : Массивы динамического хранения и
bytes
(неstring
) имеют функцию-членpush()
, которую можно использовать для добавления элемента, инициализированного нулем, в конец массива. Он возвращает ссылку на элемент, чтобы его можно было использовать какx.push().t = 2
илиx.push() = b
.
Функция возвращает новую длину массива. Итак, если в массиве уже есть 1 элемент, и я нажимаю другой, это нажатие вернет новую длину, которая равна 2. Поскольку массивы имеют нулевой индекс, вам нужно вычесть единицу из длины, чтобы получить индекс последнего элемента , что и делает пример кода, который вы разместили.
Изменить: как указал @user8555937, это уже не так, начиная с Solidity 0.6.0. Функция push больше не имеет возвращаемого значения
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
.
пользователь8555937