Модификация массива в подпрограмме - PullRequest
12 голосов
/ 03 апреля 2012

У меня есть код, который не работает так, как я ожидаю, и я был бы признателен за помощь в выяснении, как заставить его работать так, как я ожидаю.

Я бы хотелиспользуйте подпрограмму для изменения входного массива.Я подумал, что если я передам ссылку на массив, любые внесенные в него изменения будут отражены и в версии вызывающей стороны.Но, видимо, так не получается.


my @test_array = qw (zero one two three);

shift_array(\@test_array);
print "POST SUBROUTINE: $test_array[0]\n";

sub shift_array {
    my @array = @{(shift)};
    shift @array;
    print "AFTER SHIFT IN SUB: $array[0]\n";
}

Это печатает:

AFTER SHIFT IN SUB: one
POST SUBROUTINE: zero

Я ожидал, что он напечатает one оба раза.

Так что мойВопрос двоякий:

1) Почему он не ведет себя так, как мне кажется?Создает ли передача ссылки на массив копию массива?

2) Как мне получить ожидаемое поведение?Как я могу заставить подпрограмму выдвинуть один или несколько элементов с лицевой стороны копии вызывающего абонента входного массива?

Заранее благодарим за любые идеи, которые вы можете предложить.

Ответы [ 3 ]

9 голосов
/ 03 апреля 2012

Поскольку my @array - это новый массив, которому вы присвоили исходный массив с разыменованными ссылками. Это копия.

Вместо этого сделайте это:

sub shift_array {
    my $array = shift;
    shift( @$array );
}

Редактировать: Я первоначально сказал, что разыменование создает проблему, но использование @$array все еще разыменовывает ее. Как указал @mob, назначение переменной - это то, что создает новый массив вместо обновления существующей ссылки.

1 голос
/ 21 января 2017

Я предпочитаю быть более последовательным в использовании ссылок на массивы, чтобы минимизировать неоднозначность:

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

my @test_array = qw (zero one two three);

shift_array(\@test_array);
print "POST SUBROUTINE: $test_array[0]\n";

sub shift_array {
    my $ref = shift;
    shift @$ref;
    print "AFTER SHIFT IN SUB: ${$ref}[0]\n";
}
1 голос
/ 04 апреля 2012

Это один из (крошечных) случаев, когда полезны прототипы Perl.

#!/usr/bin/perl

use strict;
use warnings;

# Prototype forces the first argument to be a reference to an array    
sub shift_array (\@) {
  my $array = shift;
  shift(@$array);
  print "AFTER SHIFT IN SUB: @$array[0]\n";
}

my @test_array = qw (zero one two three);

shift_array(@test_array);
print "POST SUBROUTINE: $test_array[0]\n";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...