Question

Alors, je ne l'ai jamais su et je veux obtenir quelques éclaircissements à ce sujet. Je sais que si tu le fais

foreach (@list){

Si vous modifiez $ _ dans cette boucle, cela affectera les données réelles. Mais je ne savais pas que si vous le faisiez

foreach my $var1 (@list){

Si vous avez modifié $ var1 dans la boucle, les données réelles seront modifiées. : - / Alors, y a-t-il un moyen de boucler sur @list tout en conservant une copie en lecture seule ou une copie qui, si elle est modifiée, ne changera pas la valeur de @list?

Était-ce utile?

La solution

$ var utilise un alias pour chaque élément.

Voir http://perldoc.perl.org/perlsyn.html#Foreach-Loops

  

Si un élément de LIST est une lvalue, vous pouvez le modifier en modifiant VAR dans la boucle.   Inversement, si un élément de la liste n'est pas une valeur, toute tentative de modification de cet élément   va échouer. En d’autres termes, la variable d’index de boucle foreach est un alias implicite pour chaque   élément de la liste que vous parcourez.

Autres conseils

Le moyen le plus simple consiste simplement à le copier:

foreach my $var1 (@list) {
    my $var1_scratch = $var1;

ou

foreach my $var1 ( map 

Le moyen le plus simple consiste simplement à le copier:

foreach my $var1 (@list) {
    my $var1_scratch = $var1;

ou

foreach my $var1 ( @{ Storable::dclone( \@list ) } ) {
}

Mais si $ var1 est une référence, $ var1_scratch sera une référence à la même chose. Pour être vraiment en sécurité, vous devez utiliser quelque chose comme Storable :: dclone pour faire une copie en profondeur:

<*>

(non testé). Ensuite, vous devriez pouvoir changer en toute sécurité $ var1. Mais cela pourrait coûter cher si @list est une grosse structure de données.

, @list ) {

Mais si $ var1 est une référence, $ var1_scratch sera une référence à la même chose. Pour être vraiment en sécurité, vous devez utiliser quelque chose comme Storable :: dclone pour faire une copie en profondeur:

<*>

(non testé). Ensuite, vous devriez pouvoir changer en toute sécurité $ var1. Mais cela pourrait coûter cher si @list est une grosse structure de données.

C'est un alias, pas une référence. Si vous voulez créer vos propres alias (en dehors de for), vous pouvez utiliser Data :: Alias ??.

La seule différence entre ces boucles:

foreach (@array) { ... }
foreach my $var (@array) { ... }

est la variable de boucle. L'aliasing est une fonction de foreach , pas de la variable implicite $ _ . Notez qu'il s'agit d'un alias (un autre nom pour la même chose) et non d'une référence (un pointeur sur une chose).

Dans le cas simple (et courant), vous pouvez supprimer le crénelage en faisant une copie:

foreach my $var (@array) {
    my $copy = $var;
    # do something that changes $copy
}

Ceci fonctionne pour les valeurs scalaires ordinaires. Pour les références (ou les objets), vous devez en créer une copie complète à l’aide de Storable ou Cloner , ce qui pourrait coûter cher. Les variables liées posent également problème, perlsyn recommande d'éviter la situation.

Je ne sais pas comment forcer la variable à être par valeur plutôt que par référence dans l'instruction foreach elle-même. Vous pouvez cependant copier la valeur de $ _ .

#!/usr/perl/bin
use warnings;
use strict;

use Data::Dumper;

my @data = (1, 2, 3, 4);

print "Before:\n", Dumper(\@data), "\n\n\n";

foreach (@data) {
    my $v = 

Je ne sais pas comment forcer la variable à être par valeur plutôt que par référence dans l'instruction foreach elle-même. Vous pouvez cependant copier la valeur de $ _ .

<*>; $v++; } print "After:\n", Dumper(\@data), "\n\n\n"; __END__

Créez une copie de @list dans l'instruction for:

foreach my $var1 (() = @list) {
  # modify $var without modifying @list here
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top