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 new
sintaxis, 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!!
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 size
en una pure
función initArray
que no es posible. Debe comprender la diferencia entre view
y pure
función. Una view
función leerá el almacenamiento pero no lo cambiará y una pure
función no necesita acceso al almacenamiento y no lo cambiará.
Intenté el siguiente código para lograr lo que esperaba, pero al ejecutar initArray
la 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!
kronosapiens
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.soham lawar
kronosapiens
soham lawar
soham lawar