¿Cuál es el retorno de array.push() en Solidity?

Vi estas líneas de código en cryptozombies.io:

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

No habría tenido ningún problema si no hubiera habido "- 1" después de la función push(). Creo que el valor de retorno de la función push tiene algo que ver con el índice del objeto insertado. ¿Por qué hay un "-1"? ¿Está disponible el índice de valor de retorno del siguiente lugar libre para insertar el siguiente objeto en la matriz?

Respuestas (4)

De la documentación de Solidity :

push : las matrices de almacenamiento dinámico y bytes(no string) tienen una función miembro llamada push()que puede usar para agregar un elemento inicializado en cero al final de la matriz. Devuelve una referencia al elemento, para que pueda usarse como x.push().t = 2o x.push() = b.

La función devuelve la nueva longitud de la matriz. Entonces, si ya hay 1 elemento en la matriz, y presiono otro, ese empuje devolverá la nueva longitud, que es 2. Dado que las matrices tienen un índice cero, debe restar uno de la longitud para obtener el índice del último elemento , que es lo que hace el ejemplo de código que publicaste.

Editar: como lo señaló @ user8555937, esto ya no es cierto a partir de Solidity 0.6.0. La función push ya no tiene un valor de retorno

Esto ya no es válido para solidity 0.6.0: ethereum.stackexchange.com/a/87791/83404

Solidity 0.6.0 ha incluido algunos cambios importantes :

La función push(value) para matrices de almacenamiento dinámico ya no devuelve la nueva longitud (no devuelve nada).

La documentación ahora se lee como está:

push(x) : las matrices de almacenamiento dinámico y los bytes (no cadenas) tienen una función miembro llamada push(x) que puede usar para agregar un elemento dado al final de la matriz. La función no devuelve nada.

Ahora debe utilizar los .lengthatributos. En tu caso :

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

La array.push()función solo está disponible para arreglos de almacenamiento que tienen un tamaño dinámico. array.push()( por ejemplo, no puede hacerlo bytes32[10] arrayporque tiene un tamaño estático).

En esos casos, la pushfunción devuelve la nueva longitud de la matriz, por lo que el último índice siempre tiene la longitud -1, ya que los índices comienzan desde 0 y no desde 1;

Puede consultarlo aquí si lo desea: http://solidity.readthedocs.io/en/develop/types.html?highlight=array#members

Creo que .push()realmente significa agregar un nuevo elemento en la matriz en la mayoría de los demás idiomas.

Para devolver la longitud de la matriz, realmente tiene más sentido tener .length.