arrays - Matriz Perl vs lista
perl-data-structures (6)
En Perl, los arreglos y las listas son esencialmente lo mismo, pero su segundo ejemplo no usa ninguno. Los corchetes delimitan una referencia de matriz (un valor escalar) y "asignar" un escalar a una matriz con algo como my @array = $scalar
es equivalente a my @array = ($scalar)
. Por lo tanto, el único elemento de @array
en su segundo ejemplo es una referencia de matriz.
Tengo dos estructuras de datos en Perl:
Una matriz:
my @array2 = ( "1", "2", "3");
for $elem (@array2) {
print $elem."/n";
}
Dándome el siguiente resultado:
1
2
3
Y una lista:
my @array = [ "1", "2", "3"];
for $elem (@array) {
print $elem."/n";
}
Dando el siguiente resultado:
ARRAY(0x9c90818)
Obviamente, me gustaría iterar sobre los elementos en ambos casos, pero ¿por qué la segunda solución me da solo la referencia a esta matriz?
Las listas en Perl no son estructuras de datos, son posiciones en el código fuente, determinadas por el contexto que las rodea. Las listas son básicamente las estructuras transitorias que Perl usa para mover datos. Interactúa con ellos con toda la sintaxis de Perl, pero no puede trabajar con ellos como un tipo de datos. El tipo de datos más cercano a una lista es una matriz.
my @var = (1, 2, 3); # parens needed for precedence, they do not create a list
^ an array ^ a list
say 1, 2, 3;
^ a list
say @var;
^ a list (of one array, which will expand into 3 values before `say` is called)
Cuando escribe [1, 2, 3]
lo que está haciendo es crear una referencia de matriz escalar. Esa referencia de matriz se inicializa con la lista 1, 2, 3
, y es lo mismo que crear una matriz con nombre y tomar una referencia a ella:
[1, 2, 3] ~~ do {my @x = (1, 2, 3); /@x}
Dado que el [...]
constructo crea un escalar, debe mantenerlo en un escalar:
my $array = [1, 2, 3];
for my $elem (@$array) { # lexical loop variable
print $elem."/n";
}
Como desea operar en toda la matriz, y no solo en la referencia, coloca una @
delante de $array
que elimina la referencia de la matriz almacenada.
Los corchetes crean una matriz anónima, rellenan la matriz con el contenido de los corchetes y devuelven una referencia a esa matriz. En otras palabras,
[ "1", "2", "3" ]
es básicamente lo mismo que
do { my @anon = ("1", "2", "3"); /@anon }
Entonces el código debería verse
my $array_ref = [ "1", "2", "3" ];
for (@$array_ref) { # Short for @{ $array_ref }
print "$_/n";
}
o
my @array_of_refs = ([ "1", "2", "3" ]);
for my $array_ref (@array_of_refs) {
for (@$array_ref) {
print "$_/n";
}
}
Los corchetes se utilizan para crear una matriz anónima. Cuando se evalúa, devuelve una referencia a esta matriz, no los valores reales de la matriz.
Los paréntesis no tienen esa propiedad oculta, sino que simplemente anulan la precedence dentro de las expresiones, al igual que en matemáticas. Por ejemplo:
my @array = 1,2,3;
En realidad se evalúa así:
my @array = 1;
2,3; # causes the warning "Useless use of constant in void context"
porque el operador =
tiene mayor prioridad que las comas. Para evitar eso, usamos paréntesis cuando asignamos matrices, de esta manera:
my @array = (1,2,3);
Tu ejemplo:
my @array = [1,2,3];
es algo así como decir esto:
my @tmp = (1,2,3);
my @array = /@tmp;
Donde /
se usa para crear una referencia a la matriz @tmp
.
Si desea más aclaración, consulte la documentación pertinente .
Podría intentar y hacer algunas cosas con fines ilustrativos:
#!perl -lw # -l appends a /n to each print, -w enables warnings
use strict;
my $aryref = [1 .. 5];
print for $aryref; # Prints the stringified reference - not what you want
print for @$aryref; # Dereferencing it lets you access the array
my @ary = $aryref; # Probably not what you want
print for @ary; # Stringified reference again
print for @{$ary[0]}; # Dereference the first array element (which holds the ref)
@array = ("1", "2", "3"); Aquí 1,2,3 es el elemento de la variable @array. Por ej. $ array [0] es 1, $ array [1] es 2 y $ array [2] es 3.
@array = ["1", "2", "3"]; Perl usa referencias de matrices anónimas usando [], así que aquí básicamente solo hay un elemento que está almacenando, y esa es la referencia de una matriz ["1", "2", "3"] a la variable @array. para ex $ array [0] es "ARRAY (0x9c90818)"
Por lo tanto, mientras imprime le muestra las referencias.