ProgrammazioneSviluppatore Full-stack

Descrivi il ciclo foreach in Perl: qual è la differenza tra lavorare con copie degli elementi di un array e con i loro originali, quali insidie ci sono nell'uso della variabile di ciclo?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Perl, il ciclo foreach consente di iterare comodamente sugli elementi di un array, dove la variabile di ciclo per impostazione predefinita ($_, oppure esplicitamente specificata) fa riferimento all'elemento dell'array, anziché copiare il suo valore.

Esempio:

my @arr = (1, 2, 3); foreach my $x (@arr) { $x *= 2; } # @arr è (2, 4, 6) — gli elementi sono stati modificati!

Per ottenere esattamente una copia del valore (e non un riferimento all'elemento originale), è necessario assegnare esplicitamente la variabile:

foreach my $x ( @arr ) { # $x è un riferimento all'elemento ... } # ↓↓↓↓ foreach (@arr) { my $copy = $_; ... } # $copy è una copia, $_ è un riferimento all'elemento

Non si dovrebbe usare la stessa variabile in più cicli foreach annidati, altrimenti si possono ottenere effetti collaterali inattesi.


Domanda trabocchetto

La variabile nel ciclo foreach è una copia indipendente e può essere modificata in modo sicuro all'interno del corpo del ciclo?

Di solito si risponde: "Sì, poiché il ciclo crea da solo la variabile — si può cambiare come si vuole."

Risposta corretta:

In Perl, la variabile di ciclo per impostazione predefinita (ad esempio, foreach $var (@arr)) è un alias (riferimento) all'elemento dell'array. Qualsiasi modifica alla variabile di ciclo porta a una modifica dell'elemento originale!

Per modificare una copia temporanea — eseguire un'assegnazione esplicita all'interno del ciclo:

foreach my $elem (@arr) { my $t = $elem; $t++; # solo copia, l'array originale non viene modificato }

Storia


Storia 1

In un compito di filtraggio dei record, un programmatore ha modificato la variabile del proprio ciclo, senza sapere di star cambiando i dati originali. I calcoli successivi si sono svolti sull'array modificato, il che ha portato al calcolo errato della somma degli elementi. L'errore è emerso solo nel confronto con un campione di riferimento.


Storia 2

Un foreach annidato utilizzava la stessa variabile ($item). La variabile del ciclo interno ha sovrascritto lo stato di quella esterna, portando alla perdita dei risultati del primo passaggio, mentre parte dell'array ha avuto valori errati.


Storia 3

Un array di riferimenti a hash è stato iterato tramite foreach, e in ogni ciclo veniva assegnato un nuovo valore alla variabile di ciclo. Di conseguenza, i riferimenti sono stati "romperti" — invece dei valori di riferimento ora c'erano scalar, e la fase successiva del trattamento è fallita con un errore di tipo.