修改子程序中的数组

时间:2012-04-03 14:53:21

标签: perl

我有一些代码不能按照我期望的方式运行,而且我很感激帮助找出如何让它以我期望的方式运行。

我想使用子程序来修改输入数组。我想如果我传入对数组的引用,我对它做的任何更改都会反映在调用者的版本中。但它显然不起作用。


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 个答案:

答案 0 :(得分:9)

因为my @array是您为其指定了解除引用的原始数组的新数组。这是一份副本。

而是这样做:

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

编辑:我最初说解除引用它会产生问题,但使用@$array仍然会取消引用它。正如@mob指出的那样,分配变量是创建新数组而不是更新现有引用的原因。

答案 1 :(得分:1)

这是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";

答案 2 :(得分:1)

我更喜欢在使用数组引用时更加一致,以最大限度地减少歧义:

#!/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";
}