Array Perl vs elenco

Ho due strutture dati in Perl:

Un array:

my @array2 = ( "1", "2", "3"); for $elem (@array2) { print $elem."\n"; } 

Dandomi il seguente risultato:

 1 2 3 

E una lista:

 my @array = [ "1", "2", "3"]; for $elem (@array) { print $elem."\n"; } 

Dando il seguente risultato:

 ARRAY(0x9c90818) 

Ovviamente, vorrei ripetere gli elementi in entrambi i casi, ma perché la seconda soluzione mi fornisce solo il riferimento a questo array?

Le liste in Perl non sono strutture dati, sono posizioni nel codice sorgente, determinate dal contesto che le circonda. Le liste sono fondamentalmente le strutture transitori che Perl usa per spostare i dati. Interagisci con loro con tutta la syntax di Perl, ma non puoi lavorare con loro come tipo di dati. Il tipo di dati più vicino a un elenco è un array.

 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) 

Quando scrivi [1, 2, 3] ciò che stai facendo è creare un riferimento di array scalare. Quel riferimento di matrice è inizializzato con l’elenco 1, 2, 3 ed è lo stesso della creazione di un array con nome e prendendo un riferimento ad esso:

 [1, 2, 3] ~~ do {my @x = (1, 2, 3); \@x} 

Dato che il [...] costrutto crea uno scalare, dovresti tenerlo in uno scalare:

 my $array = [1, 2, 3]; for my $elem (@$array) { # lexical loop variable print $elem."\n"; } 

Dal momento che si desidera operare sull’intero array, e non solo sul riferimento, si pone @ davanti $array che dereferisce il riferimento dell’array memorizzato.

Le parentesi quadre vengono utilizzate per creare un array anonimo. Quando viene valutato, restituisce un riferimento a questo array, non i valori effettivi dell’array.

Le parentesi non hanno tale proprietà nascosta, ma semplicemente sovrascrivono la precedenza all’interno delle espressioni, proprio come in matematica. Per esempio:

 my @array = 1,2,3; 

In realtà è valutato in questo modo:

 my @array = 1; 2,3; # causes the warning "Useless use of constant in void context" 

perché l’operatore = ha una precedenza maggiore rispetto alle virgole. Quindi per ovviare a questo, usiamo le parentesi quando assegniamo gli array, in questo modo:

 my @array = (1,2,3); 

Il tuo esempio:

 my @array = [1,2,3]; 

è un po ‘come dire questo:

 my @tmp = (1,2,3); my @array = \@tmp; 

Dove \ viene utilizzato per creare un riferimento alla matrice @tmp .

Le parentesi quadre creano una matrice anonima, popolano la matrice con il contenuto delle parentesi e restituiscono un riferimento a tale matrice. In altre parole,

 [ "1", "2", "3" ] 

è fondamentalmente lo stesso di

 do { my @anon = ("1", "2", "3"); \@anon } 

Quindi il codice dovrebbe assomigliare

 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"; } } 

Se vuoi ulteriori chiarimenti, consulta la documentazione pertinente .

Potresti provare a fare alcune cose a scopo illustrativo:

 #!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) 

In Perl, gli array e gli elenchi sono essenzialmente la stessa cosa, ma il tuo secondo esempio non usa né l’uno né l’altro. Le parentesi quadre circondano un riferimento di matrice (un valore scalare) e “assegnano” uno scalare a un array con qualcosa come il my @array = $scalar equivale al my @array = ($scalar) . Pertanto, l’unico elemento di @array nel secondo esempio è un riferimento di matrice.

@array = (“1”, “2”, “3”); Qui 1,2,3 è l’elemento della variabile @array. Per es. $ array [0] è 1, $ array [1] è 2 e $ array [2] è 3.

@array = [“1”, “2”, “3”]; Perl usa riferimenti di array anonimi usando [], quindi qui fondamentalmente solo un elemento che stai memorizzando, e questo è il riferimento di un array [“1”, “2”, “3”] alla variabile @array. per ex $ array [0] è “ARRAY (0x9c90818)”
Quindi durante la stampa ti mostra i riferimenti.