Ricerca…


Matrice come lista

L'array è uno dei tipi di variabile base di Perl. Contiene una lista, che è una sequenza ordinata di zero o più scalari. La matrice è la variabile che tiene (e fornisce l'accesso a) i dati della lista, come è documentato in perldata .

È possibile assegnare un elenco a un array:

my @foo = ( 4, 5, 6 );

È possibile utilizzare un array ovunque sia previsto un elenco:

join '-', ( 4, 5, 6 );
join '-', @foo;

Alcuni operatori funzionano solo con gli array poiché mutano l'elenco di una matrice:

shift @array;
unshift @array, ( 1, 2, 3 );
pop @array;
push @array, ( 7, 8, 9 );

Assegnare una lista a un hash

Gli elenchi possono anche essere assegnati alle variabili hash. Quando crei un elenco che verrà assegnato a una variabile hash, si consiglia di utilizzare l' fat comma => tra chiavi e valori per mostrare la loro relazione:

my %hash = ( foo => 42, bar => 43, baz => 44 );

Il => è in realtà solo una virgola speciale che cita automaticamente l'operando alla sua sinistra. Quindi, è possibile utilizzare le virgole normali, ma il rapporto non è più chiaro:

my %hash = ( 'foo', 42, 'bar', 43, 'baz', 44 );

È inoltre possibile utilizzare le stringhe tra virgolette per l'operando a sinistra dell'enorme virgola => , che è particolarmente utile per le chiavi che contengono spazi.

my %hash = ( 'foo bar' => 42, 'baz qux' => 43 );

Per dettagli vedi operatore Comma su perldoc perlop .

Le liste possono essere passate in subroutine

Per passare la lista in una subroutine, si specifica il nome della subroutine e quindi si fornisce la lista ad essa:

test_subroutine( 'item1', 'item2' );
test_subroutine  'item1', 'item2';     # same

Internamente Perl crea alias a questi argomenti e li inserisce nell'array @_ che è disponibile all'interno della subroutine:

@_ =  ( 'item1', 'item2' ); # Done internally by perl

Si accede agli argomenti di subroutine come questo:

sub test_subroutine {
    print $_[0]; # item1
    print $_[1]; # item2
}

L'aliasing ti dà la possibilità di cambiare il valore originale dell'argomento passato alla subroutine:

sub test_subroutine {
    $_[0] +=  2;
}

my $x =  7;
test_subroutine( $x );
print $x; # 9

Per evitare modifiche involontarie dei valori originali passati nella subroutine, è necessario copiarli:

sub test_subroutine {
    my( $copy_arg1, $copy_arg2 ) =  @_;
    $copy_arg1 += 2;
}

my $x =  7;
test_subroutine $x; # in this case $copy_arg2 will have `undef` value
print $x; # 7

Per verificare quanti argomenti sono stati passati alla subroutine, controllare la dimensione di @_

sub test_subroutine {
    print scalar @_, ' argument(s) passed into subroutine';
}

Se si passano gli argomenti dell'array in una subroutine, verranno tutti appiattiti :

my @x =  ( 1, 2, 3 );
my @y =  qw/ a b c /; # ( 'a', 'b', 'c' )
test_some_subroutine @x, 'hi', @y; # 7 argument(s) passed into subroutine
# @_ =  ( 1, 2, 3, 'hi', 'a', 'b', 'c' ) # Done internally for this call

Se il tuo test_some_subroutine contiene la dichiarazione $_[4] = 'd' , per la chiamata precedente causerà $y[0] per avere il valore d seguito:

print "@y"; # d b c

Elenco di ritorno da subroutine

Puoi, ovviamente, restituire liste da sottotitoli:

sub foo {
    my @list1 =  ( 1, 2, 3 );
    my @list2 =  ( 4, 5 );

    return    ( @list1, @list2 );
}

my @list =  foo();
print @list;          # 12345

Ma non è il modo consigliato di farlo se non sai cosa stai facendo.

Mentre questo è OK quando il risultato è nel contesto LIST , nel contesto SCALARE le cose non sono chiare. Diamo un'occhiata alla prossima riga:

print scalar foo();  # 2

Perché 2 ? Cosa sta succedendo?

  1. Poiché foo() valutato nel contesto SCALAR , questo elenco ( @list1, @list2 ) viene valutato anche nel contesto SCALAR
  2. Nel contesto SCALARE , LIST restituisce il suo ultimo elemento. Qui è @list2
  3. Sempre in contesto SCALAR , array @list2 restituisce il numero dei suoi elementi. Eccolo 2 .

Nella maggior parte dei casi la strategia corretta restituirà riferimenti alle strutture dati .
Quindi nel nostro caso dovremmo fare quanto segue invece:

 return    ( \@list1, \@list2 );

Quindi il chiamante fa qualcosa del genere per ricevere i due arrayref restituiti:

 my ($list1, $list2) = foo(...);

Utilizzo di arrayref per passare l'array al sotto

L' @foo per @foo è \@foo . Questo è utile se è necessario passare un array e altre cose a una subroutine. Passare a @foo è come passare più scalari. Ma passare \@foo è un singolo scalare. All'interno della subroutine:

xyz(\@foo, 123);
...
sub xyz {
    my ($arr, $etc) = @_;
    print $arr->[0]; # using the first item in $arr. It is like $foo[0]

Hash come lista

Nell'elenco l'hash del contesto è appiattito.

my @bar =  ( %hash, %hash );

L' array @bar è inizializzato dall'elenco di due %hash hash %hash

  • entrambi gli %hash sono appiattiti
  • il nuovo elenco viene creato dagli elementi appiattiti
  • @bar array @bar è inizializzato da quella lista

È garantito che le coppie di valori-chiave vadano insieme. Le chiavi sono sempre anche indicizzate, valori - dispari. Non è garantito che le coppie di valori-chiave siano sempre appiattite nello stesso ordine:

my %hash =  ( a => 1, b => 2 );
print %hash; # Maybe 'a1b2' or 'b2a1'


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow