для каждого моего $var (@list) — $var является ссылкой?
Вопрос
Итак, я никогда не знал об этом и хочу получить некоторые разъяснения по этому поводу.Я знаю, если ты это сделаешь
foreach (@list){
если вы измените $_ в этом цикле, это повлияет на фактические данные.Но я не знал, что если ты это сделаешь
foreach my $var1 (@list){
Если бы вы изменили $var1 в цикле, это изменило бы фактические данные.:-/ Итак, есть ли способ зациклиться на @list, но сохранить переменную копией, доступной только для чтения, или копией, которая в случае изменения не изменит значение в @list ?
Решение
$ var
привязывается к каждому элементу по очереди.
См. http://perldoc.perl.org/perlsyn.html#Foreach-Loops. р>
Если какой-либо элемент LIST является lvalue, вы можете изменить его, изменив VAR внутри цикла. И наоборот, если какой-либо элемент LIST НЕ является lvalue, любая попытка изменить этот элемент не удастся. Другими словами, переменная индекса цикла foreach является неявным псевдонимом для каждого пункт в списке, над которым вы зацикливаетесь. Р>
Другие советы
Самый простой способ - просто скопировать его:
foreach my $var1 (@list) {
my $var1_scratch = $var1;
или
foreach my $var1 ( map $_, @list ) {
Но если $var1 является ссылкой, то $var1_scratch будет ссылкой на то же самое.Чтобы быть действительно безопасным, вам нужно было бы использовать что-то вроде Storable::dclone для создания глубокой копии:
foreach my $var1 ( @{ Storable::dclone( \@list ) } ) {
}
(непроверенный).Тогда вы сможете безопасно изменить $var1.Но это может быть дорого, если @list - это большая структура данных.
Это псевдоним, а не ссылка. Если вы хотите создать свои собственные псевдонимы (кроме for), вы можете использовать
Единственная разница между этими циклами: является переменной цикла. Псевдоним - это функция В простом (и обычном) случае вы можете прервать создание псевдонимов, сделав копию: Это работает для обычных скалярных значений. Для ссылок (или объектов) вам необходимо сделать глубокую копию, используя Storable или Clone , что может быть дорого. Связанные переменные также проблематичны, perlsyn рекомендует полностью избегать ситуации. р> foreach (@array) { ... }
foreach my $var (@array) { ... }
foreach
, а не неявная переменная $ _
. Обратите внимание, что это псевдоним (другое имя для той же вещи), а не ссылка (указатель на вещь). foreach my $var (@array) {
my $copy = $var;
# do something that changes $copy
}
Я не знаю, как заставить переменную быть по значению вместо по ссылке в самом операторе foreach. Вы можете скопировать значение $ _
.
#!/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 = Я не знаю, как заставить переменную быть по значению вместо по ссылке в самом операторе foreach. Вы можете скопировать значение $ _
.
<*>;
$v++;
}
print "After:\n", Dumper(\@data), "\n\n\n";
__END__
Сделайте копию @list в операторе for:
foreach my $var1 (() = @list) {
# modify $var without modifying @list here
}