Creación de una matriz 2D en memoria en Solidity

Estoy tratando de trabajar con matrices en memoria 2D en Solidity, en las que el tamaño no se conoce en tiempo de compilación. Me di cuenta de que si defino el tamaño de la matriz como constant, entonces puedo usar esta sintaxis, que compila y devuelve la matriz esperada de 10x10:

uint256 constant size = 10;

function initArray() public view {
    uint256[size][size] memory arr;
    // ...
}

Sin embargo, si defino el tamaño usando una variable, tengo problemas:

uint256 size = 10;

function initArray() public view {
    uint256[size][size] memory arr;
    // ...
}

Lo que lleva a:TypeError: Invalid array length, expected integer literal or constant expression.

Entonces trato de usar la newsintaxis, pero no puedo entender cómo usarla para arreglos 2D. Primero intento lo más simple:

uint256 size = 10;

function initArray() public view {
    uint256[][] memory arr = new uint256[][](size)(size);
    // ...
}

Esto conduce a un error: TypeError: Type is not callable, que tiene sentido. Pero entonces, ¿cómo defino el tamaño de las matrices internas? Luego probé:

uint256 size = 10;

function initArray() public view {
    uint256[][] memory arr = new uint256[][](size);
    for (uint i; i < size; i++) {
        arr[i] = new uint256[](size);
    }
    // ...
}

Esto compila pero crea una estructura de datos sin sentido. ¿Alguien puede proporcionar alguna orientación? El hecho de que esto sea posible a través de constantes me lleva a pensar que no hay una barrera fundamental, simplemente no puedo descifrar la sintaxis para pasar el tamaño a través de una variable. ¡¡Gracias!!

Respuestas (1)

uint256 size = 10;

function initArray() public pure {
    uint256[][] memory arr = new uint256[][](size);
    for (uint i; i < size; i++) {
        arr[i] = new uint256[](size);
    }
    // ...
}

El problema en el código anterior es que está intentando acceder a la variable de almacenamiento sizeen una purefunción initArrayque no es posible. Debe comprender la diferencia entre viewy purefunción. Una viewfunción leerá el almacenamiento pero no lo cambiará y una purefunción no necesita acceso al almacenamiento y no lo cambiará.

Intenté el siguiente código para lograr lo que esperaba, pero al ejecutar initArrayla función obtengo una excepción de VM.

pragma solidity ^0.4.24;

contract Foo {
    uint256 n = 10;
    function initArray() public view  {
        uint[][] memory result = new uint[][](n*n);
        for (uint i = 0; i < n; i++){
            for(uint j = 0; j < n; j++){
                result[i][j] = 1;
            }
        }

    }
}

Puede lograr la funcionalidad de matrices 2D utilizando una matriz 1D de la siguiente manera y funciona como se esperaba

pragma solidity ^0.4.24;

contract Foo {
    uint256 n = 10;
    function initArray() public view  {
        uint[] memory result = new uint[](n*n);
        for (uint i = 0; i < n; i++){
           for(uint j = 0; j < n; j++){
                result[(i*9)+j]=1; 
            }
        }

    }
}

Puedo crear una matriz 2D en la memoria. Consulte el siguiente código para el mismo:

pragma solidity ^0.4.24;

contract Foo {
    uint256 n = 10;
    function initArray(uint k,uint l) public view returns(uint)  {
        uint[][] memory arr = new uint[][](n);
        for (uint i=0; i < n; i++) {
            uint[] memory temp = new uint[](n);
            for(uint j = 0; j < n; j++){
                    temp[j]=i+j; 
                }
            arr[i] = temp;
        }
        // ...
        return arr[k][l];
    }
}

¡Espero eso ayude!

Mm, gracias por el punto sobre pure: ​​actualicé la pregunta. Y un enfoque interesante: supongo que uno podría usar una matriz 1D más grande y abstraer las dimensiones a través de la lógica de indexación. Sin embargo, me gustaría usar una matriz 2D adecuada para hacer que el código sea más semántico.
@kronosapiens, puedo crear una matriz 2D en la memoria. Consulte el código agregado
Hola @asvisosila, probé tu código pero terminé con los mismos resultados "sin sentido" que tuve antes: una matriz 2D de [[736], [3], [4], [5], [6]] valores cada uno .
@kronosapiens, ¿puede compartir el código que ha probado?
@kronosapiens Me pregunto cómo puede validar que esta es una estructura de datos "sin sentido". Puedo recuperar un valor almacenado en cada índice de una matriz, lo que la convierte en una matriz 2D de estructura de datos "sensible".