web-dev-qa-db-fra.com

Tableau Perl vs liste

J'ai deux structures de données en Perl:

Un tableau:

my @array2 = ( "1", "2", "3");

for $elem (@array2) {
    print $elem."\n";
}

En me donnant la sortie suivante:

1
2
3

Et une liste:

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

for $elem (@array) {
    print $elem."\n";
}

Donnant la sortie suivante:

ARRAY(0x9c90818)

Évidemment, j'aimerais parcourir les éléments dans les deux cas, mais pourquoi la deuxième solution me donne-t-elle uniquement la référence à ce tableau?

37
Marcin Cylke

Les listes en Perl ne sont pas des structures de données, mais des positions dans le code source, déterminées par le contexte les entourant. Les listes sont essentiellement les structures transitoires que Perl utilise pour déplacer les données. Vous interagissez avec eux avec toute la syntaxe de Perl, mais vous ne pouvez pas les utiliser comme type de données. Le type de données le plus proche d'une liste est un tableau.

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)

Lorsque vous écrivez [1, 2, 3], vous créez une référence de tableau scalaire. Cette référence à un tableau est initialisée avec la liste 1, 2, 3, ce qui revient à créer un tableau nommé et à prendre une référence à celui-ci:

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

Puisque la construction [...] crée un scalaire, vous devez le conserver dans un scalaire:

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

for my $elem (@$array) {   # lexical loop variable
    print $elem."\n";
}

Etant donné que vous souhaitez utiliser l'ensemble du tableau, et pas seulement la référence, vous placez un @ devant le $array qui déréférence la référence au tableau stocké.

78
Eric Strom

Les crochets sont utilisés pour créer un tableau anonyme. Une fois évalué, il renvoie une référence à ce tableau, pas aux valeurs réelles du tableau.

Les parenthèses n'ont pas cette propriété cachée, mais remplacent simplement precedence dans les expressions, un peu comme en math Par exemple:

my @array = 1,2,3;

Est effectivement évalué comme ceci:

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

parce que l'opérateur = a une priorité supérieure à celle des virgules. Donc, pour contourner ce problème, nous utilisons des parenthèses lors de l’affectation de tableaux, comme suit:

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

Votre exemple:

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

est un peu comme dire ceci:

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

\ est utilisé pour créer une référence au tableau @tmp.

31
TLP

Les crochets créent un tableau anonyme, remplissent le tableau avec le contenu des crochets et renvoient une référence à ce tableau. En d'autres termes,

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

est fondamentalement le même que

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

Donc, le code devrait ressembler à

my $array_ref = [ "1", "2", "3" ];

for (@$array_ref) {  # Short for @{ $array_ref }
    print "$_\n";
}

ou

my @array_of_refs = ([ "1", "2", "3" ]);

for my $array_ref (@array_of_refs) {
    for (@$array_ref) {
        print "$_\n";
    }
}
7
ikegami

Si vous souhaitez plus de précisions, voir le la documentation correspondante .

Vous pouvez essayer de faire certaines choses à titre d’illustration:

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

@array = ("1", "2", "3"); Ici 1,2,3 est l’élément de la variable @array. Par ex. $ array [0] vaut 1, $ array [1] vaut 2 et $ array [2] vaut 3. 

@array = ["1", "2", "3"]; Perl utilise des références de tableau anonymes en utilisant [], il s'agit donc ici d'un seul élément que vous stockez, à savoir la référence d'un tableau ["1", "2", "3"] à l'array variable. pour ex $ array [0] est "ARRAY (0x9c90818)"
Ainsi, lors de l'impression, il vous montre les références. 

0
Sandeep_black

En Perl, les tableaux et les listes sont essentiellement la même chose, mais votre deuxième exemple n'utilise ni l'un ni l'autre. Les crochets entourent un tableau référence (une valeur scalaire) et "attribuer" un scalaire à un tableau avec quelque chose comme my @array = $scalar est équivalent à my @array = ($scalar). Ainsi, le seul élément de @array dans votre deuxième exemple est une référence à un tableau.

0
jwodder