TypeError: la expresión tiene que ser un lvalue. ¡Pero antes el código funcionaba perfectamente!

He cambiado algunas cosas dentro de la función, pero la lógica sigue siendo la misma. Ahora, da un error en el compilador. Estoy UTILIZANDO TRUFFLE con VSC.

Función anterior:

function remove(uint ind) internal returns(address[]) {
    delete addressStorage[ind];
    for (uint j = ind; j<addressStorage.length;j++) {
        if (j==addressStorage.length-1) {
            break;
        }else {
            addressStorage[j] = addressStorage[j+1];
        }
    }
    addressStorage.length--;
    return addressStorage;
}

Actual:

function remove(uint ind, address[] array) internal returns(address[]) {
    delete array[ind];
    for (uint j = ind; j<array.length;j++) {
        if (j==array.length-1) {
            break;
        }else {
            array[j] = array[j+1];
        }
    }
    array.length--;
    return array;
}

Conseguir:

TypeError: la expresión tiene que ser un lvalue. matriz.longitud--; ^-----------^

¿Algunas ideas? ¡Gracias!

Respuestas (3)

La memoria es temporal. El almacenamiento es permanente. Por ejemplo, realizaría cálculos intermedios utilizando la memoria y luego guardaría el resultado en el almacenamiento.

Hay valores predeterminados para la ubicación de almacenamiento según el tipo de variable de que se trate:

  1. las variables de estado siempre están almacenadas
  2. los argumentos de la función están en la memoria por defecto
  3. almacenamiento de referencia de variables locales de estructura, matriz o tipo de asignación de forma predeterminada
  4. las variables locales de tipo de valor (es decir, ni matriz, ni estructura ni mapeo) se almacenan en la pila

Cuando pasa la matriz address[] como argumento de función, solidity la guardará en la memoria, es decir, hará una copia de la matriz. Los cambios realizados no serán permanentes.

Agregue "almacenamiento" en el argumento para resolver el error.

function remove(uint ind, address[] storage array) internal returns(address[]) {
delete array[ind];
for (uint j = ind; j<array.length;j++) {
    if (j==array.length-1) {
        break;
    }else {
        array[j] = array[j+1];
    }
}
array.length--;
return array;

}

Esta es mi solución:

function _pullFromArray(uint[] storage arr, uint index) internal returns(uint[]) {
    for(uint i = index; i < arr.length - 1; i++) {
        arr[i] = arr[i+1];
    }
    if (index < arr.length) {
        delete arr[arr.length - 1];
        arr.length--;
    }
    return arr;
}

El problema es que en su versión anterior estaba tratando con una matriz de almacenamiento y ahora está utilizando una matriz de memoria.

A diferencia de las matrices de almacenamiento, no es posible cambiar el tamaño de las matrices de memoria asignándolas al miembro .length.

Sí... me di cuenta de que tal vez ese era el problema. Entonces, ¿tengo que crear una función de eliminación para cambiar el tamaño de cada matriz de direcciones?